29
30:- module(text_properties, []). 31:- use_module(library(dcg/basics)). 32:- use_module(library(semweb/rdf_db)). 33:- use_module(library(semweb/rdf_litindex)). 34
35:- multifile
36 sparql:functional_property/2,
37 sparql:current_functional_property/3. 38
39:- rdf_register_prefix(tpf, 'http://cliopatria.swi-prolog.org/pf/text#'). 40
41term_expansion((sparql:functional_property(S, NS:Term0) :- Body),
42 [ (sparql:functional_property(S, Term) :- Body),
43 sparql:current_functional_property(P, P, Argc)
44 ]) :-
45 Term0 =.. [Name|Args],
46 length(Args, Argc),
47 rdf_global_id(NS:Name, P),
48 Term =.. [P|Args].
49
50
51
61sparql:functional_property(S, tpf:match(P, Pattern)) :-
62 compile_pattern(Pattern, Spec, LV),
63 search(S, P, Spec, LV).
64sparql:functional_property(S, tpf:match(P, Pattern, literal(Found))) :-
65 compile_pattern(Pattern, Spec, Found),
66 search(S, P, Spec, Found).
67
68search(S, P, prefix0(Prefix), Literal) :- !,
69 rdf_has(S, P, literal(prefix(Prefix), Literal)).
70search(S, P, Pattern, Literal) :-
71 rdf_find_literal(Pattern, Plain),
72 rdf_has(S, P, literal(exact(Plain), Literal)).
73
74compile_pattern(Literal, Spec, LitValue) :-
75 text_of(Literal, Pattern, Lang, LitValue),
76 atom_codes(Pattern, PatternCodes),
77 phrase(compile_pattern(Spec, Lang), PatternCodes).
78
79text_of(literal(lang(Lang, Pattern)), Pattern, Lang, lang(Lang,_)) :- !.
80text_of(literal(Pattern), Pattern, _, _).
81
82compile_pattern(Spec, _) -->
83 "^", !, rest(Prefix),
84 { Spec = prefix0(Prefix) }.
85compile_pattern(Spec, Lang) -->
86 blanks, "(", compile_pattern(Spec, Lang), ")", !.
87compile_pattern(Spec, Lang) -->
88 blanks,
89 simple_pattern(Left, Lang),
90 ( and
91 -> compile_pattern(Right, Lang),
92 { Spec = and(Left,Right) }
93 ; or
94 -> compile_pattern(Right, Lang),
95 { Spec = or(Left,Right) }
96 ; compile_pattern(Right, Lang)
97 -> { Spec = and(Left,Right) }
98 ; blanks
99 -> { Spec = Left }
100 ).
101
102and --> blanks, "AND", blank, !, blanks.
103or --> blanks, "OR", blank, !, blanks.
104
105simple_pattern(not(Spec), Lang) -->
106 "-", !,
107 token_pattern(Spec, Lang).
108simple_pattern(Spec, Lang) -->
109 token_pattern(Spec, Lang).
110
111token_pattern(Spec, Lang) -->
112 word(Word), !,
113 modifiers(Word, Lang, Spec).
114token_pattern(Spec, _) -->
115 number(N1),
116 ( "..",
117 number(N2)
118 -> { Spec = between(N1, N2) }
119 ; { Spec = N1 }
120 ).
121token_pattern(ge(N), _) -->
122 ">=", number(N), !.
123token_pattern(le(N), _) -->
124 "<=", number(N), !.
125token_pattern(le(N), _) -->
126 "=<", number(N), !.
127
128modifiers(Word, _, case(Word)) --> "/i", !.
129modifiers(Word, _, prefix(Word)) --> "*", !.
130modifiers(Word, L, stem(Word,L)) --> "/s", {nonvar(L)}, !.
131modifiers(Word, _, stem(Word)) --> "/s", !.
132modifiers(Word, _, sounds(Word)) --> "/S", !.
133modifiers(Word, _, Word) --> "".
140word(Word) -->
141 alpha(First),
142 alphas(Alphas),
143 { atom_codes(Word, [First|Alphas])
144 }.
145
146alphas([H|T]) -->
147 alpha(H), !,
148 alphas(T).
149alphas([]) --> [].
150
151alpha(H) -->
152 [H],
153 { code_type(H, alpha) }.
154
155rest(Atom, Codes, []) :-
156 atom_codes(Atom, Codes)