I'm trying to print all facts in my Prolog problem. Have searched the forum for a while and can't seem to find a solution to the problem. I tried the how can I print all database facts in prolog but can't seem to make it work. Im doing a menu for it, so, when I press the corresponding key, it should show me all the facts and print back the menu. Something like this (its not complete):
if_then_else(P,Q,R):- P,!,Q.
if_then_else(P,Q,R):- R.
:- dynamic client/2.
client(john,password).
client(charles,bird).
printmenu:- write('1-Print all facts').
read(X),
if_then_else(X=1,printfacts,(error,printmenu)).
printfacts:-
Why not
printfacts :-
forall(client(X, Y),format('client(~w, ~w)~n', [X, Y])).
If you just want to print the facts (not return them all in a list or whatever), then:
printfacts :-
client(X, Y),
format('client(~w, ~w)~n', [X, Y]),
false.
printfacts.
Your printmenu could be written:
printmenu :-
repeat,
write('1-Print all facts').
read(X),
( X = 1
-> printfacts
; write('Invalid response'), nl,
),
fail. % Go back to the top and reprompt
Related
Hi I am working on a PROLOG family tree question, and this is what I have so far:
/*1. Write Prolog clauses to express the following three relationships,
* given the parent/2 relationship: grandparent/2, sibling/2, cousin/2.*/
% clauses
parent(jill, amy).
parent(jill, tim).
parent(jill, john).
parent(amy, grace).
parent(amy, anna).
parent(tim, sam).
parent(tim, joel).
parent(tim, ben).
% rules
grandparent(X,Y) :-
parent(Z,Y),
parent(X,Z).
sibling(X, Y) :-
parent(Z, X),
parent(Z, Y).
cousin(X,Y) :-
parent(P, X),
parent(S, Y),
sibling(P, S).
When I put:
?- sibling(X, tim).
the output gives:
X = amy
but both john and amy are tim's sibling. The same problem happens with:
?- cousin(ben, X).
which gives:
X = grace
when both grace and anna are ben's cousins.
What changes do I need to make in order for the code to output all of tim's siblings and ben's cousins?
Thanks. :)
First of all, you've got a little bug over there.
You should correct the sibling rule - just a small hint here, try to use the rule as so
sibling(grace,grace)
and back to your issue, after you're getting first response click the ; or any of these ; n r space TAB keys, as the result you see is the first correct response. If you want to see the next correct result you need to use one of the keys above.
You can also try to use findall predicate to see all the results in the list
?- findall(X, cousin(grace, X),Z).
Z = [sam, joel, ben].
ive came this far. im new to prolog and i want to make simple figures. i want to make the input like this:
line(X,Y):-
read(Y), print(Y).
print(Y) :- write(Y).
this should be the result.
?- line(8, X).
XXXXXXXX
Not sure I've understood your question properly but how about:
line(Length,Char) :-
length(List,Length),
maplist(=(Char),List),
atomic_list_concat(List,Atom),
write(Atom).
So line(8,'X') would print XXXXXXXX and line(3,q) would print qqq.
Uses:
length/2
maplist/2
atomic_list_concat/2
You're not doing anything in your code to count down on the X argument that your pass to line predicate.
Try this code:
line(X,Y):-
read(Y),
print(X,Y).
print(0,_).
print(X,Y) :-
X>0,
write(Y),
X2 is X - 1,
print(X2,Y).
When I run that I get this:
?- line(8,X).
|: 3.
33333333
X = 3 .
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
I am doing a prolog practice which is taken from this.
What I want to do now is to change the input and output way of the program.
I need to execute the program by typing this in the console:
goldbach(100, L).
just for example, and I need to press [;] to show next result when previous one is printed on the screen.
L = [3, 97];
L = [11, 89];
L = ....
However, what I want to make is like below:
Input a number:100.
L = [3, 97].
L = [11, 89].
.....
That is the program will print "Input a number:" first and read your input, then automatically print out all possible result.
I have read sections about read() and write, but I get fail when I add these:
read_gold :-
write('Input a number:'),
read(X),
write(goldbach(X, L)).
How can I fix my code to make the program to achieve the input and output that I want? Thanks for answering.
Something like this will do literally what you're asking for, although it's not normally how one uses Prolog queries and solutions.
read_gold :-
write('Input a number:'),
read(X),
show_results(goldbach(X)).
show_results(Query) :-
call(Query, L),
write('L = '), write(L), write('.'), nl,
fail.
show_results(_).
A cleaner way to collect all of the solutions in one go is to list them using findall/3:
read_gold(Solutions) :-
write('Input a number:'),
read(X),
findall(L, goldbach(X, L), Solutions).
Or, without explicitly prompting:
read_gold(X, Solutions) :-
findall(L, goldbach(X, L), Solutions).
And query it as, for example:
?- read_gold(100, Solutions).
Solutions = [[3, 97], [11,89], ...]
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.