Falco Nogatz, Jona Kalkus, and Dietmar Seipel, University of Würzburg
Falco Nogatz, Jona Kalkus, and Dietmar Seipel, University of Würzburg
Falco Nogatz, Jona Kalkus, and Dietmar Seipel, University of Würzburg
Falco Nogatz, Jona Kalkus, and Dietmar Seipel, University of Würzburg
Head --> Body.
HeadBodyterminals, non-terminals, and Prolog predicatesTerminalProlog code;/2 and |/2,->/2,\+/1,!/1Head can be any callable term:a,a(X),a(b,2)% structure sentence --> noun_phrase, ws, verb_phrase. noun_phrase --> determiner, ws, noun. verb_phrase --> verb, ws, noun_phrase. % vocabulary determiner --> "a". % = [a] determiner --> "the". noun --> "cat". noun --> "mouse", { is_mouse_allowed }. verb --> "chases". ws --> " ". % user predicate is_mouse_allowed.
% structure sentence --> noun_phrase, verb_phrase. noun_phrase --> determiner, noun. verb_phrase --> verb, noun_phrase. % vocabulary determiner --> "a". % = [a] determiner --> "the". noun --> "cat". noun --> "mouse", { is_mouse_allowed }. verb --> "chases". % user predicate is_mouse_allowed.
?- Input = "the cat chases a mouse", phrase(sentence, Input). true. ?- Input = "the cat chases a mouse", phrase(noun_phrase, Input). false.
?- Input = "the cat chases a mouse", phrase(noun_phrase, Input, Rest). Rest = "chases a mouse".
?- Input = "the cat chases a mouse", noun_phrase(Input, Rest). Rest = "chases a mouse".
library(http/html_write)Since SWI-Prolog 6.3 (Wielemaker & Hendricks, WLPE 2013)
{| Tag || Content |}
?- Person = {| type ||
name: String!
age: Integer
books(favourite: Boolean): [Book]
friends: [Person]
|}.
Falco Nogatz and Dietmar Seipel. 2016. Implementing GraphQL as a Query Language for Deductive Databases in SWI-Prolog Using DCGs, Quasi Quotations, and Dicts. In Proc. 30th Workshop on Logic Programming (WLP 2016).
Handle embedded code as preconditions (blackbox), correct line numbers
Extend existing DCGs and Prolog systems
Reasonable overhead, pre-compilation in mind
Falco Nogatz, Jona Kalkus, and Dietmar Seipel, University of Würzburg
Falco Nogatz, Jona Kalkus, and Dietmar Seipel, University of Würzburg
% structure sentence --> noun_phrase, verb_phrase. noun_phrase --> determiner, noun. verb_phrase --> verb, noun_phrase. % vocabulary determiner --> "a". % = [a] determiner --> "the". noun --> "cat". noun --> "mouse", { is_mouse_allowed }. verb --> "chases". % user predicate is_mouse_allowed.
sentence(A, C) :- noun_phrase(A, B), verb_phrase(B, C). ... determiner([a|A], A). determiner([t,h,e|A], A). noun([c,a,t|A], A). noun([m,o,u,s,e|A], A) :- is_mouse_allowed. ...
sentence(sentence(NP,VP)) --> noun_phrase(NP), verb_phrase(VP). noun_phrase(noun_phrase(D,N)) --> determiner(D), noun(N). verb_phrase(verb_phrase(V,NP)) --> verb(V), noun_phrase(NP). determiner(determiner("a")) --> "a". determiner(determiner("the")) --> "the". noun(noun("cat")) --> "cat". noun(noun("mouse")) --> "mouse", { is_mouse_allowed }. verb(verb("chases")) --> "chases".
?- Input = "the cat chases a mouse",
phrase(noun_phrase(NP), Input, Rest).
Rest = "chases a mouse",
NP = noun_phrase(determiner("the"), noun("cat")).
Simple implementation using term expansion
Name clash
Can not use existing programs
Only successful applications
prolog_trace_interception(Port, Frame, Choice, Action) :- % retrieve unique program counter get_counter(N), % get information about current event prolog_frame_attribute(Frame,goal,Goal), prolog_frame_attribute(Frame,parent,Parent), prolog_choice_attribute(Choice,frame,ChoiceFrame), % ... % assert information as predicate `step/N` assert(step(N,Port,Frame,Goal,Parent,Choice,ChoiceFrame, ...)), % continue with the execution Action = continue.
?- Input = "the cat chases a mouse", trace, phrase(noun_phrase, Input, Rest), notrace. Rest = "chases a mouse". ?- listing(step). % ... step(3,unify,235,noun_phrase(A,[]), $dcg:call_dcg(noun_phrase,A,[]), ...). step(4,call,255,determiner(A,B), noun_phrase(A,[]), ...). % ...
Native support for backtracking
Information about current port, stack frame, choice points
No unique identifiers (in deterministic predicates)
No easy distinction between non-terminals and Prolog predicates
No way to re-use existing tracer
prolog_trace_interception(Port, Frame, Choice, Action) :- % retrieve unique program counter get_counter(N), % get information about current event prolog_frame_attribute(Frame,goal,Goal), prolog_frame_attribute(Frame,parent,Parent), prolog_choice_attribute(Choice,frame,ChoiceFrame), % ... % assert information as predicate `step/N` assert(step(N,Port,Frame,Goal,Parent,Choice,ChoiceFrame, ...)), % continue with the execution Action = continue.
vanilla(true). vanilla((A , B)) :- vanilla(A), vanilla(B). vanilla((A = B)) :- A = B. vanilla(A) :- A \= (_ , _), A \= (_ = _), A \= true, clause(A, B), vanilla(B).
?- Input = "the cat chases a mouse", vanilla(noun_phrase(Input, Rest)). Rest = "chases a mouse".
Leon Sterling and Ehud Y Shapiro. 1994. The art of Prolog: advanced programming techniques. MIT press.
mi_tree(true, true). mi_tree((A, B) , (TA, TB)) :- mi_tree(A, TA), mi_tree(B, TB). mi_tree((A = B), (A = B)) :- A = B. mi_tree(A,(A:T)) :- A \= (_ , _), A \= (_ = _), A \= true, clause(A, B), mi_tree(B, T).
?- ..., mi_tree(noun_phrase(Input, Rest), T).
Rest = "chases a mouse",
T = noun_phrase("the cat chases a mouse", "chases a mouse"):(
determiner("the cat", "cat"):true,
noun("cat", ""):true ).
mi_print(true, _Level).
mi_print((A , B), L) :-
mi_print(A, L), mi_print(B, L).
mi_print((A = B), L) :-
( A = B ~> print_indented((A = B):exit, L)
; print_indented((A = B):fail, L), fail ).
mi_print(A, L) :- L1 is L+1,
A \= (_ , _), A \= (_ = _), A \= true,
print_indented(A:call, L),
nth_clause(A, Index, Sign),
( clause(A, B, Sign), mi_print(B, L1) ~>
print_indented(A:Index:exit, L)
; print_indented(A:Index:fail, L), fail ).
print_indented(A, L) :-
Indent is 2*L, tab(Indent), writeln(A).
?- mi_print(verb_phrase("chases a dog", ""), 0).
verb_phrase("chases a dog",""):call
verb("chases a dog",_6966):call
verb("chases a dog","a dog"):1:exit
noun_phrase("a dog",""):call
determiner("a dog",_7198):call
determiner("a dog",_7198):1:fail
determiner("a dog","dog"):2:exit
noun("dog",""):call
noun("dog",""):1:fail
noun("dog",""):2:fail
determiner("a dog",_7198):2:fail
noun_phrase("a dog",""):1:fail
verb("chases a dog",_6966):1:fail
verb_phrase("chases a dog",""):1:fail
false.
mouse_phrase --> determiner, "mouse", { is_mouse_allowed }.
mouse_phrase(A, C) :- determiner(A, B), B = [m,o,u,s,e|C], is_mouse_allowed.
non-terminals and Prolog predicates
mouse_phrase(A, C) :-
'DCGBody'(determiner, A, B),
'T'("mouse", B, C),
'P'(is_mouse_allowed).
Tag{
key1: Value1,
key2: Value2, ... }
event{
step: <N>,
type: <unify | exit | fail | depth>,
redo: <Redo>,
goal: <Goal with current variable bindings>,
line: <Line number of associated clause
| 'T' | 'P' | 'DCGBody'>
}
https://github.com/jonakalkus/dcg-visualiser
?- ask(falco, +Question, -Answer).
This presentation is licensed under the
Creative Commons Attribution 4.0 International
license.
University of Würzburg
Chair for Computer Science I
falco.nogatz@uni-wuerzburg.de
http://uni-wuerzburg.de/?nogatz