Page 1 of 1

Determ besides Side Effects

Posted: 5 May 2014 13:13
by Martin Meyer
Hi Thomas and all,

the method to program for the functionality of the former reference variables described in tutorial http://wiki.visual-prolog.com/index.php ... _a_Project works well. However a little drawback is, that predicate unify/2 has to be declared as nondeterm rather than determ.

Is there some way to trick the compiler, so that unify/2 can be declared as determ while it still leaves the backtrack point to undo the binding?

If there is no such trick, can some 1st language construct in future VIP versions be invented to improve the issue? As the compiler can see, that backtracking into unify/2 will not produce an alternative solution, but only cause side effects, it might allow the predicate to be declared as "determ [besidesSideEffects]".

Best regards,
Martin

Posted: 6 May 2014 8:03
by Thomas Linder Puls
Nondeterm means it can fail and it can leave a backtrack points. Failing is obvious, and the backtrack point is necessary to undo the binding of variables when backtracking across the previous binding, i.e. the side effect you are mentioning.

The answer is no, in both cases. The backtrack point is necessary (to free the variables), so the predicate must be nondeterm.

determ-execpt-for side-effects would only act as a comment, because backtracking will takel place to invoke perform the side effects. I.e. determ-except-for-side-effects still have to leave a backtrack point (and hence can be backtracked to).

Posted: 6 May 2014 12:11
by Martin Meyer
Yes - and thx for answering, Thomas!

The determ-execpt-for-side-effects was just a quick idea of mine. Certainly you have much better ideas. Might also be, that's best to leave the issue as it is. I only intended to bring the topic to your attention.

Another idea, which comes to my mind, is "logical-determ". It would be internally handled as a nondeterm, for which an exception is raised, when the predicate produces more than one solution. :D

Many regards,
Martin

Posted: 6 May 2014 23:37
by Martin Meyer
I have experimented a little and found a way to do the trick!! In this code bindTo is a procedure, which leaves a backtrack point:

Code: Select all

interface refVar     open core       properties         bindTo : predicate{integer Val} (o).       predicates         tryGetValue : ()             -> integer Value             determ.   end interface refVar   %------   class refVar : refVar end class refVar   %------   implement refVar     open core       facts         value : integer := erroneous.         bindTo : predicate{integer} := uncheckedConvert(predicate{integer}, bindTo_mt).       predicates         bindTo_mt : (integer Val)             multi (i).     clauses         bindTo_mt(Val):-             value := Val.         bindTo_mt(_):-             value := erroneous,             fail.       clauses         tryGetValue() = value:-             not(isErroneous(value)).   end implement refVar   %------   implement main       class predicates         displayVal : (refVar RefVar)             procedure (i).     clauses         displayVal(RefVar):-             if Val = RefVar:tryGetValue() then                 stdIo::write("bound to ", Val, "\n")             else                 stdIo::write("unbound\n")             end if.       class predicates         test : (refVar RefVar)             procedure (i).     clauses         test(RefVar):-             RefVar:bindTo(123),             displayVal(RefVar),             fail.         test(RefVar):-             displayVal(RefVar).       clauses         run():-             console::init(),             test(refVar::new()).   end implement main   goal     mainExe::run(main::run).

Posted: 7 May 2014 10:51
by Thomas Linder Puls
OK, using an uncheckedConvert it is possible.