truthtable for nested equation - prolog

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.

Related

How to add a time limit to find object in prolog game?

I am coding an adventure game in swi-prolog and I am fairly new to it, but I understand the basics. I am trying to figure out how to set a time limit to give the user around 5 minutes to find objects before they disappear. For example, there is a secret key that takes you right to the enemy and if you dont find it in 5 minutes it disappears.
This is what I have so far...
/*
--> Diamond Cookie -- an adventure game
--> You must find the diamond cookie in order to save your sweet land
from being taken over by the healthy enemies.
--> Type start. to begin the story/game
*/
:- dynamic at/2, i_am_at/1, alive/1. /* Needed by SWI-Prolog. */
:- retractall(at(_, _)), retractall(i_am_at(_)), retractall(alive(_)).
/* defines the starting location. */
i_am_at(village).
/* shows how each of the rooms/areas are connected. */
path(snake, d, cave).
path(village, e, box).
path(box, w, village).
path(village, w, secret).
path(secret, e, village).
path(cave, u, snake).
path(cave, w, cave_entrance).
path(cave_entrance, e, cave).
path(cave_entrance, s, village).
path(ghouse, n, village).
path(ghouse, w, fridge).
path(fridge, e, ghouse).
path(room1, w, ghouse).
path(room1, e, room2).
path(secret, n, tree1).
path(tree1, s, secret).
path(secret, w, tree2).
path(tree2, e, secret).
path(secret, s, tree3).
path(tree3, n, secret).
path(village, n, cave_entrance) :- at(popsiclelight, in_hand).
path(village, n, cave_entrance) :-
write('You can''t go into that dark, fudgey cave without the popsiclelight and gumdrop batteries! Are you insane!?'), nl,
!, fail.
path(village, s, ghouse) :- at(gumdrop, in_hand).
path(village, s, ghouse) :-
write('Find the gumdrops to come inside!'), nl,
!, fail.
path(ghouse, e, room1) :- at(lolipopkey, in_hand).
path(ghouse, e, room1) :-
write('The unfrosted door is locked. A lolipop key is needed...'), nl,
fail.
/* where the various objects in the game are located. */
at(diamondcookie, snake).
at(lolipopkey, cave_entrance).
at(popsiclelight, ghouse).
at(candycane, room1).
at(gumdrop, box).
at(key, tree2).
/* snake is alive. */
alive(snake).
/* picking up objects. */
take(X) :-
at(X, in_hand),
write('You are already holding it!'),
nl, !.
take(X) :-
i_am_at(Place),
at(X, Place),
retract(at(X, Place)),
assert(at(X, in_hand)),
write('done.'),
nl, !.
take(_) :-
write('I don''t see that item here.'),
nl.
/* dropping unwanted object. */
drop(X) :-
at(X, in_hand),
i_am_at(Place),
retract(at(X, in_hand)),
assert(at(X, Place)),
write('done.'),
nl, !.
drop(_) :-
write('You are not holding it!'),
nl.
/* the six direction letters to move around */
n :- go(n).
s :- go(s).
e :- go(e).
w :- go(w).
u :- go(u).
d :- go(d).
/* how to move in a given direction. */
go(Direction) :-
i_am_at(Here),
path(Here, Direction, There),
retract(i_am_at(Here)),
assert(i_am_at(There)),
look, !.
go(_) :-
write('You cannot go that way...'), nl.
/* how to look around the area. */
look :-
i_am_at(Place),
describe(Place),
nl,
notice_objects_at(Place),
nl.
/* mention all the objects in the vicinity. */
notice_objects_at(Place) :-
at(X, Place),
write('There is a '), write(X), write(' here.'), nl,
fail.
notice_objects_at(_).
/* inventory to list all possesions */
inventory :-
write(' Inventory: '),nl,
list_items.
list_items :-
at(X, in_hand),
write(X), tab(10),
fail.
list_items.
/* getting killed and killing the celery and the snake. */
kill :-
i_am_at(fridge),
write('Horrible idea! You have just been turned into a vegetable by the celery...'), nl,
!, die.
kill :-
i_am_at(cave),
write('This is not working. The snake is very heavy and'), nl,
write('sticky, how does it even slither...').
kill :-
i_am_at(snake),
at(candycane, in_hand),
retract(alive(snake)),
write('You stab the snake repeatedly. Slimy juices'), nl,
write('ooze out of the spider''s back, and get all over you.'), nl,
write('You have killed it!!'),
nl, !.
kill :-
i_am_at(snake),
write('Punching the snake with your fists does no'), nl,
write('damage to it. '), nl, !.
kill :-
write('I do not see anything dangerous here.'), nl.
/* when you die. */
die :-
!, finish.
/* requests the user to perform the final halt after the game is over. */
finish :-
nl,
write('The game is over. Please enter the halt. command.'),
nl, !.
/* game instructions. */
instructions :-
nl,
write('Enter commands using standard Prolog syntax.'), nl,
write('Available commands are:'), nl,
write('start. -- to start the game.'), nl,
write('n. s. e. w. u. d. -- to go in that direction.'), nl,
write('take(Object). -- to pick up an object.'), nl,
write('drop(Object). -- to put down an object.'), nl,
write('inventory. -- to check your inventory.'), nl,
write('kill. -- to attack an enemy.'), nl,
write('look. -- to look around you again.'), nl,
write('instructions. -- to see this message again.'), nl,
write('halt. -- to end the game and quit.'), nl,
nl.
/* prints out instructions and tells where you are starting. */
start :-
instructions,
look.
/* describe the various rooms. Depending on
circumstances, a room may have more than one description. */
describe(village) :-
at(diamondcookie, in_hand),
write('Congratulations! You have recovered the diamond cookie'), nl,
write('and saved the land! You won.'), nl,
finish, !.
describe(village) :-
write('You are in the Sour Patch Village. To the north is the chocolate'), nl,
write('lava cave enterence; to the south is a small gingerbread house.'), nl,
write('To the east there is a small box that may have something in it.'),nl,
write('Your mission, if you accept, is to recover the diamond cookie'), nl,
write('and return it to this village to save the land from the healthy enemies!.'), nl,
write('There is also a secret in the map that if found in time, .'), nl.
describe(secret) :-
write('WOW... a gummy worm jungle! There are three trees. One tree is to the north and is pink/blue'), nl,
write('gummy worms. To the west there is a yellow/pink gummy worm tree. To the south there is an orange/green'), nl,
write('gummy worm tree. Maybe there is something important here...'), nl.
describe(tree1) :-
write('...just a tree.'), nl.
describe(tree2) :-
write('There is a hole in this tree with seems to be a chocoloate key.'), nl,
write('It must open something in a chocolatey place...'), nl.
describe(tree3) :-
write('Just a bunch of gummy frogs...'), nl.
describe(box) :-
write('Inside the box there are gumdrops, the kind that would go perfect in'), nl,
write('a popsiclelight to emit bright light.'), nl.
describe(ghouse) :-
write('You are in a small gingerbread house. The exit is to the north.'), nl,
write('There is a frosted door to the west, and it cracked opened.'), nl,
write('It smells a bit weird over there. There is an unfrosted door to the east.'), nl.
describe(fridge) :-
write('You are in the angry celery stick''s fridge! The celery sticks are'), nl,
write('angry and want to turn you to a vegetable. Get out while you can!'), nl.
describe(room1) :-
write('This minty smelling room has a sharp candycane, this would make a great weapon!'), nl.
describe(cave_entrance) :-
write('You are in the opening of a fudgey cave. The exit is to'), nl,
write('the south; there is a dark, round sprinkle-covered passage to'), nl,
write('the east.'), nl.
describe(cave) :-
alive(snake),
at(diamondcookie, in_hand),
write('The twizzler snake sees you with the diamond cookie and poisons you with ranch!!'), nl,
write(' ...you die within seconds....'), nl,
die.
describe(cave) :-
alive(snake),
write('There is a huge twizzler snake here! He poisons with ranch dressing,'), nl,
write('and it is directly in front of you!'), nl,
write('You should leave quietly, ASAP!'), nl, !.
describe(cave) :-
write('eghhh! There is a huge twizzler snake here, spewing ranch.'), nl,
write('It is going in circles around something sparkly.'), nl.
describe(snake) :-
alive(snake),
write('You are on top of a huge twizzler snake, standing on its sticky'), nl,
write('red skin. The smell of its poisonous ranch is awful.'), nl.
describe(snake) :-
write('YUCK! You''re on top of a giant dead snake!'), nl.
How would I add a time limit for the user to find an object within a five-minute time limit. Additionally, if they don't, how would I make it so that the object disappears after the five minutes and the user would need to find the objects the long way?

Problems with writing to file

I have some prolog codes, I print processes on terminal. Also I write to file, what I print on terminal. I put write to file functs, near every write funct. But they are not same. Writing file is not working well.
printrow([]) :- write(' '),
open('output.txt',append,OS), write(OS,' '), close(OS).
% I try to put same process for file
printrow([X|Xs]) :- printrepl(X,Y), write(' '), write(Y),
printrow(Xs), open('output.txt', append,OS),
write(OS,' '), write(OS,Y), close(OS).
printrepl(' ',' ') :- !.
printrepl(x,'X').
printrows([]) :- nl.
printrows([N|Ns]) :- write(N), write(' '),
open('output.txt', append,OS), write(OS,N), write(OS,' '),
printrows(Ns), write(OS,' \n'), close(OS).
% I can't find alternative for writef('%2r w',[X]) below,
% for writing file, I think there is bug
writek(K,List) :- nth1(K,List,X), !, writef('%2r w',[X]),
open('output.txt',append,OS), write(OS,' '), write(OS,X), close(OS).
writek(_,_) :- write(' '),
open('output.txt',append,OS),write(OS,' '), close(OS).
Can you give me advice for writing same outputs with terminal?
Here is a rewrite for writek and printrows. This could be of use.
% ---
% Printing rows (as "~w", equal to write/1) to stream Stream
% ---
printrows([],Stream) :-
format(Stream,"~n",[]).
printrows([N|Ns],Stream) :-
format(Stream,"~w ~n",[N]),
printrows(Ns,Stream).
% ---
% Printing/Appending Rows to the file named by Filename
% ---
printrows_to_file(Filename,Rows) :-
setup_call_cleanup(
open(Filename, append, Stream), % NB append
printrows(Rows,Stream),
close(Stream)).
% ---
% Printing Rows to stdout
% ---
printrows_to_stdout(Rows) :-
printrows(Rows,user_output).
% ---
% Write "w", indented by 1-based value of List[K]
% ---
writek(K,List,Stream) :-
nth1(K,List,Element),
!,
forall(between(1,Element,_),format(Stream," ",[])), % Indent
format(Stream,"w~n",[]).
writek_to_file(Filename,K,List) :-
setup_call_cleanup(
open(Filename, append, Stream), % NB append
writek(K,List,Stream),
close(Stream)).
writek_to_stdout(K,List) :-
writek(K,List,user_output).
For example:
?- printrows_to_stdout([1,2,3]).
1
2
3
true.
?- writek_to_stdout(1,[4,5,6]).
w
true.
Similarly for
?- printrows_to_file('filename.txt',[1,2,3]).
?- writek_to_file('filename.txt',1,[4,5,6]).

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?

creating a menu in prolog?

menu :-
repeat,
write(' '),nl,
write(' 1.the number of hello '),nl,
write(' '),nl,
write('enter your choice:'),nl,
read(Choice), Choice>0, Choice =<6,
doit(Choice),Choice=6.
doit(1):- numberofhello(N).
doit(6):- abort.
my_list([hello,hello,hello]).
counthowmany(_, [], 0) :- !.
counthowmany(X, [X|Q], N) :- !, counthowmany(X, Q, N1), N is N1+1.
counthowmany(X, [_|Q], N) :- counthowmany(X, Q, N).
numberofhello(N) :- my_list(L),counthowmany(hello,L,N).
now in the code above after compile buffer when I ask Prolog for a menu the menu appears
with one choice and when i enter 1 for number of hello in the list(my_list) i don't get any answer and i get a singleton variable warning while compiling .....
can anyone help me please........
A "singleton" variable is very similar, in other languages, to the warning, "Variable was assigned a value that is never used" or "A variable has been declared but never used". So your clause must do something with N in your first doit clause. You can also avoid the doit(6) :- abort. clause by allowing your menu to succeed without any choice points using a cut (!).
So, try:
menu :- repeat,
write(' '),nl,
write(' 1.the number of hello '),nl,
write(' '),nl,
write('enter your choice:'),nl,
read(Choice), Choice>0, Choice =<6,
doit(Choice), Choice=6, !.
doit(1):-
numberofhello(N),
write('Number of hello is = '), write(N), nl.
% Removed doit(6)...
...

String Compare With Write Statement

checkChar :-
nl,
write('Enter a character [press 0 to stop]: '),
get(X),
process(X).
process(X) :-
S = put(X),
0 == S,
!.
process(X) :-
write('ASCII code for <'),
put(X),
write('>:'),
write(X),
checkChar.
User will input anything they want, the prolog will translate the character into the ASCII code and display it.
The prolog will stop to execute if inputted 0, but how can i do that other than straight away compare with ASCII 48? (ASCII 48 = 0)
This is what i had tried, but it still can't stop once i enter 0.
I think this is what you may be looking for:
checkChar :-
nl,
write('Enter a character [press 0 to stop]: '),
get(X),
process(X).
process(X) :-
X =\= "0",
write('ASCII code for <'),
put(X),
write('>:'),
write(X),
checkChar.

Resources