from [mercury-users] Re: Question regardi[Dng determinism
David Glen JEFFERY
dgj at cs.mu.OZ.AU
Wed Aug 19 14:58:34 AEST 1998
Hi all,
Thought I'd move this one to mercury-developers... this thread might get
pretty technical.
On 19-Aug-1998, Thomas Charles CONWAY <conway at cs.mu.OZ.AU> wrote:
> Waugh, Sam, you write:
>
> > 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)
> ).
Yuck! IMHO, the compiler is not handling implied modes correctly.
Surely this:
moddat__add_assumption(Obj, Model, [a(Obj)|Model) :-
list__member(o(Obj,_), Model).
and this:
moddat__add_assumption(Obj, Model, [a(Obj)|Model]) :-
some [] (
list__member(o(Obj, _), Model)
).
are the same thing, given that the call to list__member/2 has no output vars!
I think that the introduction of variables for the implicit unifications of an
implied mode need to be a little more careful in preserving quantification.
Thoughts?
love and cuddles,
dgj
--
David Jeffery (dgj at cs.mu.oz.au) | Marge: Did you just call everyone "chicken"?
PhD student, | Homer: Noooo. I swear on this Bible!
Department of Computer Science | Marge: That's not a Bible; that's a book of
University of Melbourne | carpet samples!
Australia | Homer: Ooooh... Fuzzy.
More information about the developers
mailing list