Toggle navigation
?
users online
Logout
Open hangout
Open chat for current file
/* Notes for this code are at https://www.seatavern.co.za/ButtonsAndLights */ :- dynamic true/1, does/2. role(robot). init(off(p)). init(off(q)). init(off(r)). init(step(1)). legal(robot, a). legal(robot, b). legal(robot, c). next(on(p)) :- does(robot, a), true(off(p)). next(on(q)) :- does(robot, a), true(on(q)). next(on(r)) :- does(robot, a), true(on(r)). next(off(p)) :- does(robot, a), true(on(p)). next(off(q)) :- does(robot, a), true(off(q)). next(off(r)) :- does(robot, a), true(off(r)). next(on(p)) :- does(robot, b), true(on(q)). next(on(q)) :- does(robot, b), true(on(p)). next(on(r)) :- does(robot, b), true(on(r)). next(off(p)) :- does(robot, b), true(off(q)). next(off(q)) :- does(robot, b), true(off(p)). next(off(r)) :- does(robot, b), true(off(r)). next(on(p)) :- does(robot, c), true(on(p)). next(on(q)) :- does(robot, c), true(on(r)). next(on(r)) :- does(robot, c), true(on(q)). next(off(p)) :- does(robot, c), true(off(p)). next(off(q)) :- does(robot, c), true(off(r)). next(off(r)) :- does(robot, c), true(off(q)). next(step(Y)) :- true(step(X)), succ(X, Y). goal(robot, 100) :- true(on(p)), true(on(q)), true(on(r)). goal(robot, 0) :- \+(true(on(p))). goal(robot, 0) :- \+(true(on(q))). goal(robot, 0) :- \+(true(on(r))). terminal :- true(step(7)). terminal :- true(on(p)), true(on(q)), true(on(r)). findinits(Start) :- findall(Base, init(Base), Unsorted), sort(Unsorted, Start). update_state(State) :- retractall(true(_)), forall(member(Base, State), assertz(true(Base))). update_does(Player, Action) :- retractall(does(Player, _)), assertz(does(Player, Action)). findlegals(Role, Legals) :- findall(legal(Role, Action), legal(Role, Action), Unsorted), sort(Unsorted, Legals). findnext(legal(Role, Action), Next) :- update_does(Role, Action), findall(Base, next(Base), Unsorted), sort(Unsorted, Next). findreward(Role, State, goal(Role, Reward)) :- update_state(State), goal(Role, Reward). combinelists(_, [], [], [], []). combinelists(State, [legal(Player, Action)|Legals], [Next|Nexts], [Goal|Goals], [move(State, does(Player, Action), Next, Goal)|Moves]) :- combinelists(State, Legals, Nexts, Goals, Moves). generatemoves_(_, []) :- terminal. generatemoves_(Parent, Moves) :- \+terminal, role(Player), findlegals(Player, Legals), maplist(findnext, Legals, Nexts), maplist(findreward(Player), Nexts, Rewards), combinelists(Parent, Legals, Nexts, Rewards, Moves). generatemoves(Parent, Moves) :- update_state(Parent), generatemoves_(Parent, Moves), !. removestep(move(Parent, _, _, _), NoStep) :- select(step(_), Parent, NoStep). cycle(Limit, NoSteps, move(Parent, _, Child, _)) :- member(step(Limit), Parent), select(step(_), Child, NoStep), memberchk(NoStep, NoSteps). prune(Limit, Unpruned, Pruned) :- maplist(removestep, Unpruned, NoSteps), exclude(cycle(Limit, NoSteps), Unpruned, Pruned). getchildren(Parent, Visited, Children) :- generatemoves(Parent, Moves), findall(Move, (member(Move, Moves), \+memberchk(Move, Visited)), NoDuplicates), sort(NoDuplicates, Children). depthfirst(_, [], RGraph, Graph) :- reverse(RGraph, Graph). depthfirst(Limit, [move(Parent, Action, Child, Goal)|Frontier], Visited, Acc) :- memberchk(step(Depth), Child), Depth \== Limit, depthfirst(Limit, Frontier, [move(Parent, Action, Child, Goal)|Visited], Acc). depthfirst(Limit, [move(Parent, Action, Child, Goal)|Frontier], Visited, Acc) :- memberchk(step(Limit), Child), getchildren(Child, Visited, GrandChildren), append(GrandChildren, Frontier, NewFrontier), depthfirst(Limit, NewFrontier, [move(Parent, Action, Child, Goal)|Visited], Acc). iterative_deepening(_, Graph, Graph) :- memberchk(move(_, _, _, goal(_, 100)), Graph). iterative_deepening(Depth, GraphIn, Acc) :- \+memberchk(move(_, _, _, goal(_, 100)), GraphIn), depthfirst(Depth, GraphIn, [], Unpruned), Unpruned \== GraphIn, prune(Depth, Unpruned, GraphOut), succ(Depth, Limit), iterative_deepening(Limit, GraphOut, Acc). getactions(Start, Graph, [Node|_], Actions, [Action|Actions]) :- member(move(Start, Action, Node, _), Graph). getactions(Start, Graph, [Child|Path], Actions, Acc) :- member(move(Parent, Action, Child, _), Graph), Parent \== Start, getactions(Start, Graph, [Parent, Child|Path], [Action|Actions], Acc). route(Actions) :- findinits(Start), getchildren(Start, [], G1), prune(1, G1, G2), iterative_deepening(2, G2, G3), % format("~w~n", [G3]), member(move(_, _, End, goal(_, 100)), G3), getactions(Start, G3, [End], [], Actions).