[mercury-users] Getting 'any' insts to ground
Lee Naish
lee at cs.mu.oz.au
Tue Nov 11 12:44:36 AEDT 1997
In message <199711101256.XAA15090 at mundook.cs.mu.OZ.AU>Fergus wrote:
> :- pred is_ground(var(T), maybe(T)).
> :- mode is_ground(in(any), out) is cc_multi.
>
>Operationally, is_ground(Var, Result) returns Result = no
>if Var is non-ground, and Result = yes(Value) if Var is ground;
If this is guartanteed to be the case then isn't it possible to use
something like promise_one_solution to write a correct non-logical
version which is det/semidet? Of course you have to tell a little
white lie: is_ground has one solution.
I think its important that at least the documentation and predicate
naming makes it reasonably obvious that this kind of thing is BAD.
I suspect many novice Mercury programmers would not realise that calling
is_ground inside promise_one_solution is telling a lie - they would
think that its a legitimate way of getting the mode checker to stop
producing those stupid error messages.
There is a fine line between logical and nonlogical code/languages once
you introduce pruning. In Goedel its possible to implement a version of
is_var which works *if* you have a fixed clause selection rule. Since
Goedel doesn't guarantee this, you can argue that its theoretically
impossible write a correct version of is_var (of course in practice you
can write one which works, since the only existing Goedel implementation
does used a fixed selection rule).
In Mercury there are options to fix the selection rule, which makes
things more dangerous, but the mode system forces us to use cc_ modes
and keeps things logical. The logic is lost when the promise in
promise_one_solution is broken. I think it fine to have predicates such
as promise_one_solution (though this name is poor - six possible
interpretations are "there is at least/exactly/at most one solution according
to the declarative/procedural semantics"), but it is desirable to have
debugging support for the cases where promises are broken (since this is
one source of bugs).
Ideally there should be some debugging/paranoid version/mode for such
predicates which allows promises to be checked. For example,
promise_one_solution called with a nondet procedure could find all
solutions and check there is the right number. The "right" thing to do
for promise_one_solution calling a cc_nondet procedure would be to have
a nondet version of the procedure and call that instead, as above. This
might be a bit tricky to arrange - we would need non-cc versions of
each cc procedure in general. However, I think its important that there
are ways of automatically checking that no promise is broken, for a
particular input to the program.
lee
More information about the users
mailing list