Prune a choice point but not the choice points since then

18 views
Skip to first unread message

Jan Rosecký

unread,
Mar 16, 2016, 6:47:47 AM3/16/16
to SWI-Prolog
Hello! 
I am struggling with the following: I need to cut a choice point depending on a result I get after the choice. If any other choice points have been created since then, I need to preserve them. E.g.:

member( A, [a,b] ), member(B, [1,2]), % here I need to decide, whether to cut the first member (e.g. according to the result of the second member).

prolog_cut_to does not really help here, does it? Obviously, it could be possible to overcome with asserts/flags but is it possible even without these?

Thanks in advance for any tips!
Honza

Jan Wielemaker

unread,
Mar 16, 2016, 7:40:46 AM3/16/16
to Jan Rosecký, SWI-Prolog
On 03/16/2016 11:47 AM, Jan Rosecký wrote:
> Hello!
> I am struggling with the following: I need to cut a choice point
> depending on a result I get after the choice. If any other choice points
> have been created since then, I need to *preserve* them. E.g.:
>
> |
> member(A,[a,b]),member(B,[1,2]),%here I need to decide,whether to cut
> the first member (e.g.according to the result of the second member).
> |
>
> prolog_cut_to does not really help here, does it? Obviously, it could be
> possible to overcome with asserts/flags but is it possible even without
> these?

As it stands, that doesn't exist. Its not that useful as it typically
does not allow you to reclaim space unless you implement stack
compaction for the local stack. Implementing it isn't that hard,
basically use the choice-point examination predicates to find the proper
source code and add a foreign predicate that changes the type of the
choice point into CHP_DEBUG.

Instead of flags, you probably want to use non-backtrakable data. E.g.,
you can do

State = can_backtrack(true),
( Something
; arg(1, State, true),
Else
),
More(State).

Then inside More: nb_setarg(1, State, false). As we cannot reclaim space
easily anyway, this isn't much worse than being able to kill a specific
choice point.

Cheers --- Jan


Jan Rosecký

unread,
Mar 16, 2016, 5:03:55 PM3/16/16
to SWI-Prolog, ros...@celebriosoftware.com
I see, okey. I am implementing some kind of attribute inheritance and overriding in a (possibly infinite) hierarchy. E.g.

object generic
   
-> attribute1 = a
object specific1
   
-> attribute1 = b
   
-> attribute1 = c
object specific2

When asking for values of attribute1 on specific1, I want to get b and c, on specific2, I want to get a.
I have a predicate nondeterministically generating (transitive) ancestors of a given object (from nearest to far most). So the best approach for me would be

get_transitive_ancestor( Ancestor ), get_attribute( Ancestor, Attribute, Value ), destroy_the_first_choicepoint().

Now, I'm overcoming the issue using asserts but there is some overhead as while getting an attribute, the predicate may be called again, so I have to identify the query and do the clean-up too.

Honza



Dne středa 16. března 2016 12:40:46 UTC+1 Jan Wielemaker napsal(a):
Reply all
Reply to author
Forward
0 new messages