Prolog If statement fact - prolog

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?

Related

Print elements of a list but handle last element differently

I have written a predicate that prints out each element in the list except the last. The last element should be handled differently; it should print LAST! instead. This is what I have.
write_data([]).
write_data([X]) :-
!, write('LAST!'), nl.
write_data([X | Rest]) :-
write(x), nl,
write_data(Rest).
Is there a better way? Is there a way to do this without the cut?
You can avoid the cut, by performing unification with a list that has at least two elements, like:
write_data([]).
write_data([_]) :-
write('LAST!'),
nl.
write_data([X|Rest]) :-
Rest = [_|_],
write(X), nl,
write_data(Rest).
We can furthermore avoid the double unpacking with a helper predicate:
write_data([]).
write_data([H|T]) :-
write_data(T, H).
write_data([], _) :-
write('LAST!'), nl.
write_data([H|T], X) :-
write(X), nl,
write_data(T, H).
A common definition for a last/2 predicate that provides access to the last element of a list is:
last([Head| Tail], Last) :-
last(Tail, Head, Last).
last([], Last, Last).
last([Head| Tail], _, Last) :-
last(Tail, Head, Last).
When called with the first argument bound to a closed list, the auxiliary predicate, last/3, avoids spurious choice-points assuming a Prolog system implementing, as common, first-argument indexing. Can you modify this predicate to do what you want?
The general rule of thumb for cut removal is to note what was true in the clause that contains the cut , then make sure that is false in the other clause(s) .
Thus :
write_data([]).
write_data([X]) :-
/*!,*/write('LAST!'), nl.
write_data([X | Rest]) :-
dif(Rest,[]) , /**/
write(x), nl,
write_data(Rest).

truthtable for nested equation

I am trying to create a prolog program to print out the truthtable of a statement. It works fine for the example truthtable(A,B,and(A,B)),
but if I try truthable(A,B,or(A,and(A,B))) it doesn't work and shows everything as false.
and(true,true):- true.
and(false,true):-false.
and(true,false):-false.
and(false,false):-false.
or(true,true):-true.
or(false,true):-true.
or(true,false):-true.
or(false,false):-false.
non(true):-false.
non(false):-true.
evaluate(E, true) :- E, !.
evaluate(E, false).
bool(true).
bool(false).
truthtable(A,B,E):-
bool(A),
bool(B),
write(A),
write(' \t '),
write(B),
write(' \t '),
evaluate(E, R),
write(R),
nl,
fail.
Also what can I do if I want the user to add any number of inputs for example A,B and C not only A and B.

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.

save answer in Prolog using tell function

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').

Resources