Skip to content

Commit c2b8eed

Browse files
committed
added natural language
1 parent e480dbd commit c2b8eed

File tree

6 files changed

+134
-36
lines changed

6 files changed

+134
-36
lines changed

README.md

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,47 @@ ancestor(celine,fanny)
5050
5151
true.
5252
```
53+
If the example file contains a specification to "read" the atoms, then the trace above is formatted accordingly. For instance, given the following
54+
specifications
55+
56+
```
57+
%!read mother(A,B) as: A is the mother of B
58+
%!read father(A,B) as: A is the father of B
59+
%!read parent(A,B) as: A is the parent of B
60+
%!read ancestor(A,B) as: A is the ancestor of B
61+
```
62+
in file ``ancestor.pl``, we get the following
63+
output instead:
64+
65+
```
66+
anna is the ancestor of fanny
67+
anna is the parent of fanny
68+
anna is the mother of fanny
69+
;
70+
daniel is the ancestor of fanny
71+
daniel is the parent of fanny
72+
daniel is the mother of fanny
73+
;
74+
tim is the ancestor of fanny
75+
tim is the parent of anna
76+
tim is the mother of anna
77+
anna is the ancestor of fanny
78+
anna is the parent of fanny
79+
anna is the mother of fanny
80+
;
81+
celine is the ancestor of fanny
82+
celine is the parent of daniel
83+
celine is the father of daniel
84+
daniel is the ancestor of fanny
85+
daniel is the parent of fanny
86+
daniel is the mother of fanny
87+
88+
```
89+
5390
By default, the output is also saved in file ```temp.txt``` as follows:
5491

5592
```
56-
[[call(0,ancestor(anna,fanny)),call(1,parent(anna,fanny)),call(2,mother(anna,fanny))],[call(0,ancestor(daniel,fanny)),call(1,parent(daniel,fanny)),call(2,mother(daniel,fanny))],[call(0,ancestor(tim,fanny)),call(1,parent(tim,anna)),call(2,mother(tim,anna)),call(1,ancestor(anna,fanny)),call(2,parent(anna,fanny)),call(3,mother(anna,fanny))],[call(0,ancestor(celine,fanny)),call(1,parent(celine,daniel)),call(2,father(celine,daniel)),call(1,ancestor(daniel,fanny)),call(2,parent(daniel,fanny)),call(3,mother(daniel,fanny))]]
93+
[[[call(0,ancestor(anna,fanny),"anna is the ancestor of fanny"),call(1,parent(anna,fanny),"anna is the parent of fanny"),call(2,mother(anna,fanny),"anna is the mother of fanny")],[call(0,ancestor(daniel,fanny),"daniel is the ancestor of fanny"),call(1,parent(daniel,fanny),"daniel is the parent of fanny"),call(2,mother(daniel,fanny),"daniel is the mother of fanny")],[call(0,ancestor(tim,fanny),"tim is the ancestor of fanny"),call(1,parent(tim,anna),"tim is the parent of anna"),call(2,mother(tim,anna),"tim is the mother of anna"),call(1,ancestor(anna,fanny),"anna is the ancestor of fanny"),call(2,parent(anna,fanny),"anna is the parent of fanny"),call(3,mother(anna,fanny),"anna is the mother of fanny")],[call(0,ancestor(celine,fanny),"celine is the ancestor of fanny"),call(1,parent(celine,daniel),"celine is the parent of daniel"),call(2,father(celine,daniel),"celine is the father of daniel"),call(1,ancestor(daniel,fanny),"daniel is the ancestor of fanny"),call(2,parent(daniel,fanny),"daniel is the parent of fanny"),call(3,mother(daniel,fanny),"daniel is the mother of fanny")]]
5794
```
5895
The tracer can also be used as a shell command:
5996

examples/ancestor.pl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
%!read mother(A,B) as: A is the mother of B
2+
%!read father(A,B) as: A is the father of B
3+
%!read parent(A,B) as: A is the parent of B
4+
%!read ancestor(A,B) as: A is the ancestor of B
5+
16
mother(tim, anna).
27
mother(anna, fanny).
38
mother(daniel, fanny).

parser.pl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,17 @@
1616
clauses(T).
1717
clauses([]) --> [].
1818

19+
clause(reading(Atom,String,ListVars)) -->
20+
[punct("%")],
21+
[punct("!")],
22+
[word("read")],
23+
atom_ast(Atom),
24+
[word("as")],
25+
[punct(":")],
26+
comment_ast(C),
27+
[cntrl("\n")],
28+
{process_text(Atom,C,StringList,ListVars),atomics_to_string(StringList," ",String)}.
29+
1930
clause(visible([(Pred,N)|R])) -->
2031
[punct("%")],
2132
[word("visible")],
@@ -149,3 +160,18 @@
149160
[word(N2)],
150161
{string_concat(N1,".",Temp),string_concat(Temp,N2,N),term_string(Prob,N)},
151162
[cntrl("\n")].
163+
164+
process_text(Atom,C,String,ListVars) :-
165+
vars_atom(Atom,Vars),
166+
pt(Vars,C,String,ListVars).
167+
168+
pt(_Vars,[],[],[]).
169+
pt(Vars,[V|R],["~p"|String],[var(V)|ListVars]) :-
170+
member(var(V),Vars),!,
171+
pt(Vars,R,String,ListVars).
172+
pt(Vars,[W|R],[W|String],ListVars) :-
173+
pt(Vars,R,String,ListVars).
174+
175+
176+
vars_atom(Atom,Vars) :-
177+
Atom =.. [_|Vars].

temp.txt

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1 @@
1-
ancestor(anna,fanny)
2-
parent(anna,fanny)
3-
mother(anna,fanny)
4-
;
5-
ancestor(daniel,fanny)
6-
parent(daniel,fanny)
7-
mother(daniel,fanny)
8-
;
9-
ancestor(tim,fanny)
10-
parent(tim,anna)
11-
mother(tim,anna)
12-
ancestor(anna,fanny)
13-
parent(anna,fanny)
14-
mother(anna,fanny)
15-
;
16-
ancestor(celine,fanny)
17-
parent(celine,daniel)
18-
father(celine,daniel)
19-
ancestor(daniel,fanny)
20-
parent(daniel,fanny)
21-
mother(daniel,fanny)
1+
[[call(0,ancestor(anna,fanny),"anna is the ancestor of fanny"),call(1,parent(anna,fanny),"anna is the parent of fanny"),call(2,mother(anna,fanny),"anna is the mother of fanny")],[call(0,ancestor(daniel,fanny),"daniel is the ancestor of fanny"),call(1,parent(daniel,fanny),"daniel is the parent of fanny"),call(2,mother(daniel,fanny),"daniel is the mother of fanny")],[call(0,ancestor(tim,fanny),"tim is the ancestor of fanny"),call(1,parent(tim,anna),"tim is the parent of anna"),call(2,mother(tim,anna),"tim is the mother of anna"),call(1,ancestor(anna,fanny),"anna is the ancestor of fanny"),call(2,parent(anna,fanny),"anna is the parent of fanny"),call(3,mother(anna,fanny),"anna is the mother of fanny")],[call(0,ancestor(celine,fanny),"celine is the ancestor of fanny"),call(1,parent(celine,daniel),"celine is the parent of daniel"),call(2,father(celine,daniel),"celine is the father of daniel"),call(1,ancestor(daniel,fanny),"daniel is the ancestor of fanny"),call(2,parent(daniel,fanny),"daniel is the parent of fanny"),call(3,mother(daniel,fanny),"daniel is the mother of fanny")]]

tracer.pl

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
*/
4949

5050
:- dynamic cl/3.
51+
:- dynamic reading/3.
5152
:- dynamic comment/1.
5253
:- dynamic visible/1.
5354
:- dynamic unsafe/1.
@@ -86,6 +87,7 @@
8687

8788
load(File) :-
8889
retractall(cl(_,_,_)),
90+
retractall(reading(_,_,_)),
8991
retractall(visible(_)),
9092
retractall(unsafe(_)),
9193
retractall(comment(_)),
@@ -94,19 +96,34 @@
9496
retractall(explanations(_)),
9597
retractall(counter(_)),assertz(counter(0)),
9698
read_problog_program(File,Program),
99+
%print(Program).
97100
file_base_name(File,FileNameExt),
98101
string_concat(FileName,'.pl',FileNameExt),
99102
assertz(filename(FileName)),
100103
%nl,print(read_problog_program(File,Program)),nl,
101104
replace_vars(Program,ProgramVars),
102105
%nl,print(replace_vars(Program,ProgramVars)),nl,
103-
assert_clauses(ProgramVars),!.
106+
assert_clauses(ProgramVars).
104107
%query(Atom),
105108

109+
process_traces([],[]).
110+
process_traces([T|R],[TT|RR]) :-
111+
process_trace(T,TT),
112+
process_traces(R,RR).
113+
114+
process_trace([],[]).
115+
process_trace([call(N,A)|R],[call(N,A,S)|RT]) :-
116+
(reading(A,String,Vars) -> format(string(S),String,Vars)
117+
; term_string(A,S)),
118+
process_trace(R,RT).
119+
106120
run(Q) :-
107121
findall(Trace,eval(0,Q,Trace),Traces),
108-
print_traces(Traces),
109-
write_traces(Traces).
122+
%print(Traces),nl,
123+
process_traces(Traces,Traces2),
124+
%print(Traces2),nl,
125+
print_traces(Traces2),
126+
write_traces(Traces2).
110127

111128
write_traces(Trace) :-
112129
open('temp.txt',write,Stream),
@@ -122,9 +139,11 @@
122139
print_trace(Trace),
123140
print(';'),nl,
124141
print_traces(R).
142+
125143
print_trace([]).
126-
print_trace([call(N,A)|R]) :-
127-
tab(N*3),format("~p~n",[A]),
144+
print_trace([call(N,_A,S)|R]) :-
145+
% tab(N*3),format("~p~n",[A]),
146+
tab(N*3),format(S),nl,
128147
print_trace(R).
129148

130149
eval(_,[],[]).
@@ -196,7 +215,7 @@
196215
assert_clauses([unsafe(Preds)|R]) :-
197216
!,assert_unsafe_preds(Preds),
198217
assert_clauses(R).
199-
assert_clauses([Cl|R]) :-
218+
assert_clauses([Cl|R]) :-
200219
assertz(Cl),
201220
assert_clauses(R).
202221

@@ -217,6 +236,12 @@
217236
replace_vars(R,RT).
218237
replace_vars([unsafe(L)|R],[unsafe(L)|RT]) :-
219238
replace_vars(R,RT).
239+
replace_vars([reading(Q,String,Vars)|R],[reading(Q3,String,V4)|RT]) :-
240+
V =.. [foo|Vars],
241+
rvars([Q,V],[Q2,V2],[],-1),
242+
varnumbers([Q2,V2],[Q3,V3]),
243+
V3 =.. [_|V4],
244+
replace_vars(R,RT).
220245
replace_vars([comment(C)|R],[comment(C)|RT]) :-
221246
replace_vars(R,RT).
222247
replace_vars([query(Q)|R],[query(Q3)|RT]) :-

tracer_shell.pl

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
recognised_option(['-g',F],goal(F)).
5858

5959
:- dynamic cl/3.
60+
:- dynamic reading/3.
6061
:- dynamic comment/1.
6162
:- dynamic visible/1.
6263
:- dynamic unsafe/1.
@@ -95,6 +96,7 @@
9596

9697
load(File) :-
9798
retractall(cl(_,_,_)),
99+
retractall(reading(_,_,_)),
98100
retractall(visible(_)),
99101
retractall(unsafe(_)),
100102
retractall(comment(_)),
@@ -103,24 +105,40 @@
103105
retractall(explanations(_)),
104106
retractall(counter(_)),assertz(counter(0)),
105107
read_problog_program(File,Program),
108+
%print(Program).
106109
file_base_name(File,FileNameExt),
107110
string_concat(FileName,'.pl',FileNameExt),
108111
assertz(filename(FileName)),
109112
%nl,print(read_problog_program(File,Program)),nl,
110113
replace_vars(Program,ProgramVars),
111114
%nl,print(replace_vars(Program,ProgramVars)),nl,
112-
assert_clauses(ProgramVars),!.
115+
assert_clauses(ProgramVars).
113116
%query(Atom),
114117

118+
process_traces([],[]).
119+
process_traces([T|R],[TT|RR]) :-
120+
process_trace(T,TT),
121+
process_traces(R,RR).
122+
123+
process_trace([],[]).
124+
process_trace([call(N,A)|R],[call(N,A,S)|RT]) :-
125+
(reading(A,String,Vars) -> format(string(S),String,Vars)
126+
; term_string(A,S)),
127+
process_trace(R,RT).
128+
115129
run(Q) :-
116130
findall(Trace,eval(0,Q,Trace),Traces),
117-
print_traces(Traces),
118-
write_traces(Traces).
131+
%print(Traces),nl,
132+
process_traces(Traces,Traces2),
133+
%print(Traces2),nl,
134+
print_traces(Traces2),
135+
write_traces(Traces2).
119136

120137
write_traces(Trace) :-
121138
open('temp.txt',write,Stream),
122139
set_prolog_IO(user_input,Stream,user_error),
123-
(cli_output(raw) -> print(Trace); print_traces(Trace)),
140+
print(Trace),
141+
%print_traces(Trace),
124142
close(Stream).
125143

126144
print_traces([]).
@@ -130,9 +148,11 @@
130148
print_trace(Trace),
131149
print(';'),nl,
132150
print_traces(R).
151+
133152
print_trace([]).
134-
print_trace([call(N,A)|R]) :-
135-
tab(N*3),format("~p~n",[A]),
153+
print_trace([call(N,_A,S)|R]) :-
154+
% tab(N*3),format("~p~n",[A]),
155+
tab(N*3),format(S),nl,
136156
print_trace(R).
137157

138158
eval(_,[],[]).
@@ -204,7 +224,7 @@
204224
assert_clauses([unsafe(Preds)|R]) :-
205225
!,assert_unsafe_preds(Preds),
206226
assert_clauses(R).
207-
assert_clauses([Cl|R]) :-
227+
assert_clauses([Cl|R]) :-
208228
assertz(Cl),
209229
assert_clauses(R).
210230

@@ -225,6 +245,12 @@
225245
replace_vars(R,RT).
226246
replace_vars([unsafe(L)|R],[unsafe(L)|RT]) :-
227247
replace_vars(R,RT).
248+
replace_vars([reading(Q,String,Vars)|R],[reading(Q3,String,V4)|RT]) :-
249+
V =.. [foo|Vars],
250+
rvars([Q,V],[Q2,V2],[],-1),
251+
varnumbers([Q2,V2],[Q3,V3]),
252+
V3 =.. [_|V4],
253+
replace_vars(R,RT).
228254
replace_vars([comment(C)|R],[comment(C)|RT]) :-
229255
replace_vars(R,RT).
230256
replace_vars([query(Q)|R],[query(Q3)|RT]) :-
@@ -254,4 +280,3 @@
254280
rvars_args(R,VarList,N,RR,NVarList,NN).
255281

256282

257-

0 commit comments

Comments
 (0)