> I was talking to Harold about the DTB document again and we agreed both
> that we do not really like the "negative guards", because they seem to
> introduce some special form of negation, which is a bit weird, as
> otherwise negation is not part of bld...
>
> Now let's take the use case, which I suppose brought up the whole idea
> about negative guards:
>
>
> I assume the idea was that guards where meant to do some type checking
> to prevent other builtins to fail with an error... so we need these for
> instance to right something like:
>
> q(X+1) :- p(X) if X is numeric.
> q(0) :- p(X) if X is not Numeric.
the most natural way to write these rules is:
q(X+1) :- p(X), isNumeric(X).
q(0) :- p(X), isNotNumeric(X).
In fact, I would be surprised if we would not have the isNumeric and
isNotNumeric built-in predicates. (we already have built-ins such as
numeric-add and numeric-subtract, so it will be rather silly not to have
the isNumeric and isNotNumeric predicates)
Now, your first example is an approximation of this, which can be
simplified, as Michael pointed out.
Your second example is an encoding that one can only understand if one
would know about the intricacies of the way RIF deals with errors.
Guards are a way to prevent errors occurring in the first place, thereby
not requiring users to know about the intricacies of the semantics of
errors.
Then, I would argue that having "negation" in built-in predicates does
not introduce negation in the language.
In fact, we already have negation in our built-in predicates. For
example, greater-than is the negation of less-or-equal.
Perhaps negation is also not the proper term in this context. Perhaps
we should rather talk about "complement". Greater-than is the
complement of less-or-equal; numeric-equal is the complement of
numeric-unequal; isNumeric is the complement of isNotNumeric.
Implementing the complement of a built-in predicate is as complex as
implementing the built-in predicate itself.
Finally, complement of built-in predicates is quite different from the
(default) negation usual in logic programs.
Consider isNotString(ex:myiri). This statement may be true in some
models, and false in others.
Consider now not isString(ex:myiri). This statement is true in the
minimal model, because it is not known that ex:myiri is a string.
Best, Jos
>
> i.e. to make a case distinction, concerning whether the arbuments are
> "allowed" for the built-in which should e "guarded".
>
> Now with the current means we would need to write this something like
> as follows:
>
> q(numeric-add(X,1)) :- p(X), isInteger(X) .
> q(numeric-add(X,1)) :- p(X), isDecimal(X) .
> q(numeric-add(X,1)) :- p(X), isLong(X) .
>
> q(0) :- p(X), isNotInteger(X), isNotLong(X), isNotDecimal(X).
>
> whereas we could write this simpler and without negative guards if we
> just add one more guard except the current datatypeguards:
>
> q(numeric-add(X,1)) :- p(X), isInteger(X) .
> q(numeric-add(X,1)) :- p(X), isDecimal(X) .
> q(numeric-add(X,1)) :- p(X), isLong(X) .
> q(0) :- p(X), isError(X+1).
>
> I don't know whether this solves all use cases for negative guards, but,
> before buying into sneaking in some form of negation which we can later
> on have in dialects with negation for free... maybe adding the isError()
> guard for the moment and leaving out the negative guards would do for
> the moment?
>
> Axel
>
>
--
debruijn@inf.unibz.it
Jos de Bruijn, http://www.debruijn.net/
----------------------------------------------
One man that has a mind and knows it can
always beat ten men who haven't and don't.
-- George Bernard Shaw