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.
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.