How does pruning choice points in the code below make it more efficient (Prolog)? -
in code given below, there !
(cut) prunes choice point efficiency. pretty reverse
predicate , agent_do_moves
predicate essential.
solve_task(task,cost):- agent_current_position(oscar,p), solve_task_a(task,[b(0,0,p)],[],r,cost,_newpos),!, % prune choice point efficiency reverse(r,[_init|path]), agent_do_moves(oscar,path).
the cut in above examples has following effect:
ideally, commits search might happen within solve_task_a/6
first answer found. frees resources finding further answers improves space consumption.
scope problems
however, @ same time, might hide further answers agent_current_position/2
. of course, not make sense have further answers goal, might error happens sleep while, become active still undiscovered in worst possible situation.
for reason, preferable write instead of cut
..., once( solve_task_a( ... ) ), ...
this limits scope precisely want express.
steadfastness problem
but not possible source of problems. see variable cost
. instantiated when call solve_task(task, cost)
or not? lot of guessing here. @ least variable might influence answer prolog commit to. solve_task(task, 99)
, solve_task(task, cost), cost = 99
might produce different answers. in fact, latter might fail. predicates have such problems said lack steadfastness.
to illustrate how steadfastness lost in such situation consider (runnable) sketch of (already improved) program:
solve_task(task,cost):- %agent_current_position(oscar,p),once(solve_task_a(task,[b(0,0,p)],[],r,cost,_newpos)), true. solve_task_a(_, _, _, _, 20, _). solve_task_a(_, _, _, _, 30, _).
now
?- solve_task(a, cost). cost = 20. ?- solve_task(a, 30). true. ?- solve_task(a, cost), cost = 30. false.
there easy way out of problem cleanly testing variable cost
, e.g. cost >= 0
produces instantiation error should cost
uninstantiated variable. if want (as indicate in comment) determine cost, need put so:
solve_task(task,cost):- %agent_current_position(oscar,p),once(solve_task_a(task,[b(0,0,p)],[],r,costx,_newpos)), costx = cost true.
in manner can sure cost
cannot influence outcome of solve_task_a/6
(euh - provided there no aliasing between cost
, task
- let's assume moment). 1 says output unifications put behind commit.
many people tell such care not needed, never use solve_task(task, cost)
given cost. might case, sure remember it? , sure source code remember (without dynamic check)? such implicit assumptions accumulate degree mental capacities overburdened.
there not easy way out. quite possible stick logical purity logical-purity. in case, not have remember such assumptions.
in case, recommend not go these parts of prolog moment. rather stick successor-arithmetics, clpfd, , other clean, monotonic programs preserving logical-purity. there lot learn!
Comments
Post a Comment