Question regarding determinism

Thomas Charles CONWAY conway at
Wed Aug 19 14:27:54 AEST 1998

Waugh, Sam, you write:
> [I assume that di and uo still only work for io__state.]

Di and uo mean "destructive input" and "unique output" which are
"unique -> dead" and "free -> unique" respectively. These modes
may be used objects of any type, however, you cannot backtrack over
calls containing a mode of di since the final inst is "dead".
There is a mode mdi which is "mostly destructive input" which
is "mostly unique -> mostly dead" which is backtrackable, however,
looking at your code, in and out are the right modes to be
using (at least with the current compiler - eventually you may
get some performance gain using unique modes, but I wouldn't worry
about it for the time being).

> This is defined as semidet, because I want it to fail under
> certain conditions.  In this case the code marks an assumption
> about an existing object; but that only makes sense if the
> object exists.
> Now the type is along the lines of:
> :- type moddat == list(elements).
> :- type elements ---> o(string, string); a(string).
> where o is definition of the object and it's class and a is a
> statement about a defined object.
> My initial implementation was:
> moddat__add_assumption(Obj, Model, [a(Obj)|Model) :-
> 	list__member(o(Obj,_), Model).
> which runs into problems as list__member with a non-ground term
> is nondet.  How can I make this semidet?  I don't care what class
> the object is, as along as it exists.

A quantifier is the right thing, but to get it right you need to
know that the compiler flattens unifications, so your code becomes
something like (I've used more sensible variable names than the
compiler uses for its automatically introduced variables):

moddat__add_assumption(Obj, Model, Result) :-
	list__member(Element, Model),	% <---
	Element = o(Tmp, _),		% <---
	Tmp = Obj,			% <---
	Thing = a(Obj),
	Result = [Thing|Model].

Now, the determinism problem is because call to member is nondeterministic,
and is not within a scope with no output bindings. What we need to do is
restrict the scope of element by putting the three marked lines above in
a restricted scope:

moddat__add_assumption(Obj, Model, Result) :-
	some Element (
		list__member(Element, Model),
		Element = o(Tmp, _),
		Tmp = Obj
	Thing = a(Obj),
	Result = [Thing|Model].

This we can now simplify till we get almost your original code:

moddat__add_assumption(Obj, Model, [a(Obj)|Model]) :-
	some [] (
		list__member(o(Obj, _), Model)

Thomas Conway <conway at>
Nail here [] for new monitor.  )O+

More information about the users mailing list