:- module(tag_match, [ tag_match/5, % +Tag1, +Tag2, -MatchType, -Tag1Data, -Tag2Data find_tag_concept/3 % +Tag, -Resource, -HitData ]). :- use_module(library(find_resource)). :- use_module(library(semweb/rdf_db)). :- use_module(library(semweb/rdfs)). :- use_module(library(semweb/rdf_litindex)). :- use_module(library(snowball)). %% tag_match(+Tag1, +Tag2, -Match, -Tag1Data, -Tag2Data) % % Succeeds if Tag1 and Tag2 match exactly or there is a relation % between the concepts associcated with the Tags. TagData provides % info about how the matching concepts are found. tag_match(T, T, exact, TData, _) :- !, ( find_tag_concept(T, _R, Hit) -> tag_data(Hit, TData) ; TData = [] ). tag_match(T1, T2, stem, TData, _) :- snowball(dutch, T1, T), snowball(dutch, T2, T), !, ( find_tag_concept(T, _R, Hit) -> tag_data(Hit, TData) ; TData = [] ). tag_match(T1, T2, Type, T1Data, T2Data) :- find_tag_concept(T1, R1, Hit1), find_tag_concept(T2, R2, Hit2), tag_concept_match(R1, R2, Type), !, tag_data(Hit1, T1Data), tag_data(Hit2, T2Data). tag_concept_match(R, R, synonym) :- !. tag_concept_match(R1, R2, specific) :- ancestor_of(R1, R2), !. tag_concept_match(R1, R2, generic) :- ancestor_of(R2, R1), !. tag_data(hit(D,R,P,L), Data) :- Data = [uri=R, match=L, matchtype=P, distance=D, type=Type], tag_concept_type(R, Type). %% find_tag_concept(?String, ?Concept) % % String is a label of Concept. find_tag_concept(Tag, R, Hit) :- rdf_equal(rdfs:label, Label), rdf_equal(skos:prefLabel, PrefLabel), LabelList = [PrefLabel-0, Label-1 ], Options = [match(stem), attributes(LabelList), distance(true) ], find_resource_by_name(Tag, Hits, Options), member(Hit, Hits), Hit = hit(D,R,_,_), D =< 10. %% tag_concept_type(+Concept, -Type) % % Type is one of predefined tag types of Concept. tag_concept_type(R, Class) :- rdf(R, rdf:type, Class), \+ rdf_equal(Class, skos:'Concept'), !. tag_concept_type(R, Scheme) :- rdf(R, skos:inScheme, Scheme), !. tag_concept_type(R, Concept) :- rdf_equal(Concept, skos:'Concept'), rdf(R, rdf:type, Concept), !. tag_concept_type(_, unknown). %% ancestor_of(+R, +Ancestor) % % True if Ancestor is reachable by skos:broader from R. ancestor_of(R, A) :- rdf_reachable(R, skos:broader, A).