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?
I want to be able to let users choose a few options and not all to get the hypothesis to show. Example: The user is interested in computers, programming, and technology but not apps, i still want the system to show that user can major in Information Technology.
This code is able to run in swi-prolog.
go:-
hypothesis(Major),
write('I believe that the student can major in '),
write(Major), nl,
write('GOOD LUCK '),
undo.
/*Hypothesis that should be tested*/
hypothesis(informationTechnology) :-
informationTechnology, !.
hypothesis(informationTechnology_or_medicine) :-
informationTechnology_or_medicine, !.
hypothesis(medicine) :- medicine, !.
hypothesis(hospitality) :- hospitality, !.
hypothesis(business) :- business, !.
hypothesis(law) :- law, !.
hypothesis(unknown). /* no diagnosis*/
/*Hypothesis Identification Rules*/
informationTechnology :-
verify(computers),
verify(apps),
verify(technology),
verify(programming),
write('Courses to choose from:'), nl,
write('1: Computer Science'), nl,
write('2: Information Systems'), nl,
write('3: Security Technology'), nl,
write('Please wear warm cloths Because'), nl.
informationTechnology_or_medicine :-
verify(computers),
verify(science),
verify(communication),
verify(problem_solving),
verify(research),
verify(technology),
write('Courses to choose from:'), nl,
write('1: Computer Science'), nl,
write('2: Information Systems'), nl,
write('3: Security Technology'), nl,
write('These are the available courses.'), nl.
medicine :-
verify(science),
verify(health),
verify(research),
verify(helping_people),
write('Courses to choose from:'), nl,
write('1: Nursing'), nl,
write('2: Medicine'), nl,
write('3: Physiotherapy'), nl,
write('These are the available courses.'), nl.
hospitality :-
verify(helping_people),
verify(management),
verify(communication),
verify(planning),
write('Courses to choose from:'), nl,
write('1: Hotel Management'), nl,
write('2: Culinary arts'), nl,
write('3: Human Resources Management'), nl,
write('4: Public Relations'), nl,
write('These are the available courses.'), nl.
business :-
verify(money_making),
verify(apps),
verify(economy),
verify(communication),
write('Courses to choose from:'), nl,
write('1: Business Administration'), nl,
write('2: Accounting and Finance'), nl,
write('3: Marketing and E-commerce'), nl,
write('4: International Business'), nl,
write('These are the available courses.'), nl.
law :-
verify(law),
verify(justice),
verify(government),
verify(politics),
verify(reading),
write('Courses to choose from:'), nl,
write('1: Criminology'), nl,
write('2: Political Science'), nl,
write('3: Psychology'), nl,
write('4: Forensics'), nl,
write('These are the available courses.'), nl.
/* how to ask questions */
ask(Question) :-
write('Do you have interest in:'),
write(Question),
write('? '),
read(Response), nl,
( (Response == yes ; Response == y)
->
assert(yes(Question)) ;
assert(no(Question)), fail).
:- dynamic yes/1,no/1.
/*How to verify something */
verify(S) :-
(yes(S)
->
true ;
(no(S)
->
fail ;
ask(S))).
/* undo all yes/no assertions*/
undo :- retract(yes(_)),fail.
undo :- retract(no(_)),fail.
undo.
Just add another hypothesis like this:
hypothesis(informationTechnology_without_apps) :-
informationTechnology_without_apps, !.
and a new hypothesis identification rule:
informationTechnology_without_apps :-
verify(computers),
verify(technology),
verify(programming),
write('Courses to choose from:'), nl,
write('1: Computer Science'), nl,
write('2: Information Systems'), nl,
write('3: Security Technology'), nl,
write('Please wear warm cloths Because'), nl.
I have been tasked with creating a General Expert System in Prolog which you can plug in different knowledge bases to, so it has to be general. The knowledge base that I have to provide with the Expert System is the Farmer Goat Wolf and Cabbage Puzzle. I am having a really tough time designing the knowledge base and the general inference engine.
After a couple days of searching, I have found a bunch of examples of Expert Systems for the bird hierarchy and some other odds and ends, but they don't seem to help me wrap my head around how to put this project together.
I was just wondering if anyone has some good examples or material of how to design Expert Systems in Prolog or where good places to look are?
Thanks for your help as it is much appreciated.
PS. I would prefer not to purchase material as this is my last month of school and it will be highly unlikely that I will be doing much Prolog programming after this course is finished.
Thanks and Regards,
D
EDIT
Here is my knowledge base.
% Order is Farmer, Goat, Wolf, Cabbage
start_state :: state(west_side, west_side, west_side, west_side).
fact :: current(X, X, X, X) :-
end_state :: state(X, X, X, X),
X = east_side.
move_goat ::
if
state(X, X, W, C) and
opp(X, Y) and
(unsafe(state(Y, Y, W, C)))
then
current(Y, Y, W, C).
move_wolf ::
if
state(X, G, X, C) and
opp(X, Y) and
(unsafe(state(Y, G, Y, C)))
then
current(Y, G, Y, C).
move_cabbage ::
if
state(X, G, W, X) and
opp(X, Y) and
(unsafe(state(Y, G, W, Y)))
then
current(Y, G, W, Y).
% Move the object to the other side of the river
opp(west_side, east_side).
opp(east_side, west_side).
% Is the new state unsafe
fact :: unsafe(state(X,Y,Y,C)) :- opp(X,Y).
fact :: unsafe(state(X,Y,W,Y)) :- opp(X,Y).
Here is the Expert System I am trying to retrofit my knowledge base to.
:-op(900, xfx, ::).
:-op(800, xfx, was).
:-op(880, xfx, then).
:-op(870, fx, if).
:-op(600, xfx, from).
:-op(600, xfx, by).
:-op(550, xfy, or).
:-op(540, xfy, and).
:-op(300, fx, 'derived by').
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
main :-
consult('FarmerKB.pl'),
assertz(lastindex(0)),
assertz(wastold(dummy, false, 0)),
assertz(end_answers(dummy)),
expert.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
expert :-
getquestion(Question),
( answeryes(Question)
;
answerno(Question)
).
answeryes(Question) :-
markstatus(negative),
explore(Question, [], Answer),
positive(Answer),
markstatus(positive),
present(Answer), nl,
write('More Solutions?'),
getreply(Reply),
Reply = no.
answerno(Question) :-
retract(no_positive_answer_yet), !,
explore(Question, [], Answer),
negative(Answer),
present(Answer), nl,
write('More Negative Solutions?'),
getreply(Reply),
Reply = no.
markstatus(negative) :-
assertz(no_positive_answer_yet).
markstatus(positive) :-
retract(no_positive_answer_yet), !
;
true.
getquestion(Question) :-
nl, write('Question Please'), nl,
read(Question).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
explore(Goal, Trace, Goal is true was 'found as a fact') :-
fact :: Goal.
explore(Goal, Trace, Goal is TruthValue was 'derived by' Rule from Answer) :-
Rule :: if Condition then Goal,
explore(Condition, [Goal by Rule | Trace], Answer),
truth(Answer, TruthValue).
explore(Goal1 and Goal2, Trace, Answer) :- !,
explore(Goal1, Trace, Answer1),
continue(Answer1, Goal1 and Goal2, Trace, Answer).
explore(Goal1 or Goal2, Trace, Answer) :-
exploreyes(Goal1, Trace, Answer)
;
exploreyes(Goal2, Trace, Answer).
explore(Goal1 or Goal2, Trace, Answer1 and Answer2) :- !,
not(exploreyes(Goal1, Trace, _)),
not(exploreyes(Goal2, Trace, _)),
explore(Goal1, Trace, Answer1),
explore(Goal2, Trace, Answer2).
explore(Goal, Trace, Goal is Answer was told) :-
useranswer(Goal, Trace, Answer).
exploreyes(Goal, Trace, Answer) :-
explore(Goal, Trace, Answer),
positive(Answer).
continue(Answer1, Goal1 and Goal2, Trace, Answer) :-
positive(Answer1),
explore(Goal2, Trace, Answer2),
( positive(Answer2),
Answer = Answer1 and Answer2
;
negative(Answer2),
Answer = Answer2
).
continue(Answer1, Goal1 and Goal2, _, Answer1) :-
negative(Answer1).
truth(Question is TruthValue was found, TruthValue) :- !.
truth(Answer1 and Answer2, TruthValue) :-
truth(Answer1, true),
truth(Answer2, true), !,
TruthValue = true
;
TruthValue = false.
positive(Answer) :-
truth(Answer, true).
negative(Answer) :-
truth(Answer, false).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
getreply(Reply) :-
read(Answer),
means(Answer, Reply), !
;
nl, write('Answer unknown, try again please'), nl,
getreply(Reply).
means(yes, yes).
means(y, yes).
means(no, no).
means(n, no).
means(why, why).
means(w, why).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
useranswer(Goal, Trace, Answer) :-
askable(Goal, _),
freshcopy(Goal, Copy),
useranswer(Goal, Copy, Trace, Answer, 1).
useranswer(Goal, _, _, _, N) :-
N > 1,
instantiated(Goal), !,
fail.
useranswer(Goal, Copy, _, Answer, _) :-
wastold(Copy, Answer, _),
instance_of(Copy, Goal), !.
useranswer(Goal, _, _, true, N) :-
wastold(Goal, true, M),
M >= N.
useranswer(Goal, Copy, _, Answer, _) :-
end_answers(Copy),
instance_of(Copy, Goal), !,
fail.
useranswer(Goal, _, Trace, Answer, N) :-
askuser(Goal, Trace, Answer, N).
askuser(Goal, Trace, Answer, N) :-
askable(Goal, ExternFormat),
format(Goal, ExternFormat, Question, [], Variables),
ask(Goal, Question, Variables, Trace, Answer, N).
ask(Goal, Question, Variables, Trace, Answer, N) :-
nl,
( Variables = [], !,
write('Is it true:')
;
write('Any (more) solution to:')
),
write(Question), write('?'),
getreply(Reply), !,
process(Reply, Goal, Question, Variables, Trace, Answer, N).
process(why, Goal, Question, Variables, Trace, Answer, N) :-
showtrace(Trace),
ask(Goal, Question, Variables, Trace, Answer, N).
process(yes, Goal, _, Variables, Trace, true, N) :-
nextindex(Next),
Next1 is Next + 1,
( askvars(Variables),
assertz(wastold(Goal, true, Next))
;
freshcopy(Goal, Copy),
useranswer(Goal, Copy, Trace, Answer, Next1)
).
process(no, Goal, _, _, _, false, N) :-
freshcopy(Goal, Copy),
wastold(Copy, true, _), !,
assertz(end_answers(Goal)),
fail
;
nextindex(Next),
assertz(wastold(Goal, false, Next)).
format(Var, Name, Name, Vars, [Var/Name | Vars]) :-
var(Var), !.
format(Atom, Name, Atom, Vars, Vars) :-
atomic(Atom), !,
atomic(Name).
format(Goal, Form, Question, Vars0, Vars) :-
Goal =..[Functor | Args1],
Form =..[Functor | Forms],
formatall(Args1, Forms, Args2, Vars0, Vars),
Question =..[Functor | Args2].
formatall([], [], [], Vars, Vars).
formatall([X | XL], [F | FL], [Q | QL], Vars0, Vars) :-
formatall(XL, FL, QL, Vars0, Vars1),
format(X, F, Q, Vars1, Vars).
askvars([]).
askvars([Variable/Name | Variables]) :-
nl, write(Name), write(' = '),
read(Variable),
askvars(Variables).
showtrace([]) :-
nl, write('This was you question'), nl.
showtrace([Goal by Rule | Trace]) :-
nl, write('To investigate, by'),
write(Rule), write(','),
write(Goal),
showtrace(Trace).
instantiated(Term) :-
numbervars(Term, 0, 0).
instance_of(Term, Term1) :-
freshcopy(Term1, Term2),
numbervars(Term2, 0, _), !,
Term = Term2.
freshcopy(Term, FreshTerm) :-
asserta(copy(Term)),
retract(copy(FreshTerm)), !.
nextindex(Next) :-
retract(lastindex(Last)), !,
Next is Last + 1,
assertz(lastindex(Next)).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
present(Answer) :-
nl, showconclusion(Answer),
nl, write('Would you like to see how?'),
getreply(Reply),
( Reply = yes, !,
show(Answer)
;
true
).
showconclusion(Answer1 and Answer2) :- !,
showconclusion(Answer1), write('and '),
showconclusion(Answer2).
showconclusion(Conclusion was Found) :-
write(Conclusion).
show(Solution) :-
nl, show(Solution0), !.
show(Answer1 and Answer2, H) :- !,
show(Answer1, H),
tab(H), write(and), nl,
show(Answer2, H).
show(Answer was Found, H) :-
tab(H), writeans(Answer),
nl, tab(H),
write('was '),
show1(Found, H).
show1(Derived from Answer, H) :- !,
write(Derived), write('from'),
nl, H1 is H + 4,
show(Answer, H1).
show1(Found, _) :-
write(Found), nl.
writeans(Goal is true) :- !,
write(Goal).
writeans(Answer) :-
write(Answer).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Negate the current statement
not(P) :-
P, !, fail
;
true.
Thanks,
D
For people that are struggling with similar issues, I was able to work with the tutorial from amzi.com and George Luger's examples to come up with a working knowledge base / Expert System for the Farmer and Goat problem.
http://www.amzi.com/ExpertSystemsInProlog/xsiptop.php
http://www.cs.unm.edu/~luger/
http://www.cs.unm.edu/~luger/ai-final/code/
As this was the toughest part I am only posting the knowledge base.
rule((move(St1, Cu1) :-
(start(state(St1, St2, St3, St4)),
switch(state(St1, St2, St3, St4), state(Cu1, Cu2, Cu3, Cu4), [state(St1, St2, St3, St4)]))), 100).
start(state(east_side, east_side, east_side, east_side)).
end(state(west_side, west_side, west_side, west_side)).
switch(state(F1, G1, W1, C1), state(F2, G2, W2, C2), History) :-
is_end(state(F1, G1, W1, C1))
;
move_state(state(F1, G1, W1, C1), state(F2, G2, W2, C2)),
not(is_history(state(F2, G2, W2, C2), History)),
switch(state(F2, G2, W2, C2), state(F3, G3, W3, C3), [state(F2, G2, W2, C2)|History]).
move_state(state(X,X,W,C), state(Y,Y,W,C)) :-
opp(X,Y), not(unsafe(state(Y,Y,W,C))).
move_state(state(X,G,X,C), state(Y,G,Y,C)) :-
opp(X,Y), not(unsafe(state(Y,G,Y,C))).
move_state(state(X,G,W,X), state(Y,G,W,Y)) :-
opp(X,Y), not(unsafe(state(Y,G,W,Y))).
move_state(state(X,G,W,C), state(Y,G,W,C)) :-
opp(X,Y), not(unsafe(state(Y,G,W,C))).
opp(east_side, west_side).
opp(west_side, east_side).
unsafe(state(X, Y, Y, C)) :- opp(X, Y).
unsafe(state(X, Y, W, Y)) :- opp(X, Y).
is_end(state(F1, G1, W1, C1)) :-
end(state(Side1, Side2, Side3, Side4)),
Side1 == F1, Side2 == G1,
Side3 == W1, Side4 == C1.
is_history(state(F1, G1, W1, C1), []) :-
fail.
is_history(state(F1, G1, W1, C1), [HisHead|HisTail]) :-
state(F1, G1, W1, C1) == HisHead
;
is_history(state(F1, G1, W1, C1), HisTail).
% This has to be added if there are no ask-able questions otherwise the program will fail
askable(test).