save answer in Prolog using tell function - prolog

i am doing a Prolog project and below is my code.
:- dynamic yes/1,no/1.
:- dynamic n_angle/1.
go :- hypothesize(Shape),
write('Yes I know the shape you talking about is a '),
write(Shape),
write('!!!!'),
undo.
hypothesize(circle) :- circle,!.
circle :- not(verify(width)),
verify(radius),
not(verify(height)),
verify(diameter_equal_2_radius).
ask(Question):-
write('Has the shape '),
write(Question),
write('?'),
read(Response),
nl,
((Response == yes ; Response == y)
-> assert(yes(Question));
assert(no(Question)), fail).
verify(S) :-
(yes(S) -> true ;
(no(S) -> fail ;
ask(S))).
save_file:- tell('D:ansSave.txt').
/* undo all yes/no assertions */
undo :- retract(yes(_)),fail.
undo :- retract(no(_)),fail.
undo :- retract(n_angle(_)),fail.
undo.
and the result will be like this.
?- go.
Has the shape width?n.
Has the shape radius?y.
Has the shape height?n.
Has the shape diameter_equal_2_radius?y.
Yes I know the shape you talking about is a circle!!!!
true.
i want to save the result as shown above to a txt file.
but when i try to put the save_file to the ask function
ask(Question):-
save_file,
write('Has the shape '),
write(Question),
write('?'),
read(Response),
nl,
told,
((Response == yes ; Response == y)
-> assert(yes(Question));
assert(no(Question)), fail).
it will overwrite the result every time. can anyone tell me how to solve this ? thanks in advance.

If you don't want to overwrite previous file content, consider using append/1.
So your rule must be:
save_file:- append('D:ansSave.txt').

Related

Resolution Tree in prolog

Can anyone please teach me how to draw this resolution tree in prolog and write the rules and fact, in this topic which is Medical Diagnosis.
check:-
checkfor(Disease),
write('You probably have '),
write(Disease),
nl,
undo.
checkfor(sick):- sick.
sick:-
checkSymptom(sneezing),
checkSymptom(runny_nose),
checkSymptom(stuffy_nose),
checkSymptom(sore_throat),
nl.
askQuestion(Question):-
write('Do you have the symptom '),
write(Question),
write('?'),
read(Reply),
nl,
( ( Reply == yes ; Reply == y)
->
assert(yes(Question));
assert(no(Question)),fail).
:- dynamic yes/1,no/1.
checkSymptom(S) :-
( yes(S)
->
true ;
( no(S)
->
fail ;
askQuestion(S))).
undo :- retract(yes(_)),fail.
undo :- retract(no(_)),fail.
undo.

what is a good way to link exclusive statements in prolog?

We were asked to write a menu based calculator on an exam where we were to return control to the menu once the desired calculation had been performed.
I wrote the following code as my solution and while the professor deemed it as correct I still think there must be a better way to return control to the menu after the the first clause to table(A,N) returns false.
Please note that I've redacted quite a bit of my original code that was irrelevant to my question.
menu :-
write('Enter a choice: '),
read(C),
choice(C).
choice(1) :-
table(5).
table(N) :-
A is 1,
start(A,N).
table(A,N) :-
K is A*N,
write(K),
nl,
A1 is A+1,
A1=<10,
table(A1, N)
;
menu.
I'm very new to prolog so the question might not be appropriately worded. Please let me know if that's the case.
You can use repeat/0 to loop forever.
menu :-
repeat, % add this line
write('Enter a choice: '),
read(C),
choice(C).
choice(1) :-
table(5).
table(N) :-
A is 1,
start(A,N).
table(A,N) :-
K is A*N,
write(K),
nl,
A1 is A+1,
A1=<10,
table(A1, N).
% ; % delete this line
% menu. % delete this line

Prolog If statement fact

I want to state a unique fact in my Prolog data base to change the outcome of my if statement.
My code is as follows:
suspect(Killer, mrBoddy) :-
affair(mrBoddy, Y),
married(X,Y),
write('Killer= '),
write(X), nl;
greedy(X),
write('Killer= '),
write(X), nl.
The output is
?- suspect(Killer, mrBoddy).
Killer= profPlum
true ? ;
Killer= colMustard
yes
My Facts
affair(mrBoddy, msGreen).
affair(mrBoddy,missScarlet).
married(profPlum, msGreen).
rich(mrBoddy).
greedy(colMustard).
motive_to_kill_affair(profPlum).
motive_to_kill_greed(colMustard).
I want to add a fact that will change the output to only one "Killer". Doesn't matter who it is. How could I achieve this?

Execution tree meta interpreting

I have tracing meta-interpreter made from my previous questions here and I would like to make similar meta-interpreter but this time for making execution trees.
I've made something like this below using similar to same code found on the web and techniques from my previous questions.
clause_tree(true,_,true) :- !, true.
clause_tree((G,R),Trail,(TG,TR)) :-
!,
clause_tree(G,Trail,TG),
clause_tree(R,Trail,TR).
clause_tree(G,_,prolog(G)) :-
(predicate_property(G,built_in) ;
predicate_property(G,compiled) ),
call(G).
clause_tree(G,Trail,tree(G,T)) :-
clause(G,Body),
clause_tree(Body,[G|Trail],T).
why(G) :-
call_with_depth_limit(
catch(
clause_tree(G,[],T),
cut,
fail),
30,
_Message),
nl,
draw_tree(T,0).
draw_tree(tree(Root,Branches),Tab) :- !,
tab(Tab),
write(Tab),
write(': '),
write(Root),
nl,
Tab1 is Tab + 1,
draw_tree(Branches,Tab1).
draw_tree((B,Bs),Tab) :- !,
draw_tree(B,Tab),
draw_tree(Bs,Tab).
draw_tree(Node,Tab) :-
tab(Tab),
write(Tab),
write(': '),
write(Node),
nl.
%example program for testing
%?-p(X).
p(X) :- a(X).
p(X) :- b(X),c(X), d(X),e(X).
p(X) :- f(X).
b(Y) :- g(Y), h(Y).
b(1).
b(2).
a(1).
c(1).
c(2).
d(1).
d(2).
e(2).
f(3).
g(2).
g(1).
h(2).
How can I alter this interpreter that it displays branches that fails and that tree is only one with all solutions? Consider that trees are done only for similar programs like example program written in code if that matters.
I am using swi-prolog.
Edit : I am trying to achieve something like this but in textual form.

how can I make prolog print query results when running a prolog script

I'm new to prolog and want to save all queries in a file instead of typing them by hand.
I have these facts in facts.pl:
likes(wallace, cheese).
likes(grommit, cheese).
likes(wendolene, sheep).
friend(X, Y) :- \+(X = Y), likes(X, Z), likes(Y, Z).
After reading the answer of this question,
I come up with the following code queries.pl:
main :-
write(likes(wallace, cheese)),
halt.
:- initialization(['facts.pl']).
:- initialization(main).
Here I want to examine if likes(wallace, cheese) holds,
what I expected is outputing something like yes or no but the actual output is likes(wallace, cheese)
I've googled a lot and attempted
X = likes(wallace, cheese), write(X).
X is likes(wallace, cheese), write(X).
X := likes(wallace, cheese), write(X).
but none of them works.
It might be a really easy question for you, but I have no idea about how to get things right.
BTW, I'm using GNU Prolog 1.4.1
I think you need a way to 'tag' each query: here a simple way
query(likes(wallace, cheese)).
query(likes(mickey, whisky)).
% service predicates, check the library and use that if available
forall(X,Y) :- \+ (X, \+ Y).
writeln(T) :- write(T), nl.
main :-
forall(query(Q), (Q -> writeln(yes:Q) ; writeln(no:Q))),
halt.

Resources