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 . in case, not have remember such assumptions.


in case, recommend not go these parts of prolog moment. rather stick , , , other clean, monotonic programs preserving . there lot learn!


Comments

Popular posts from this blog

c# - Validate object ID from GET to POST -

node.js - Custom Model Validator SailsJS -

php - Find a regex to take part of Email -