Previous: Recursion, BOM Table of Contents Next: Stratification    Negation

Existential Variables

Existential variables are those which only appear once in the rule (alias singleton variables). They have a meaning `there exists' in positive goals and `there does not exists in negated goals.

    print_nice_people(X) <- person(X), ~nasty(X).  
    print_nice_people(`everybody is nice') <- ~nasty(Y).
The variable Y in the last rule and W in the previous one could be replaced by an underscore; it is called an existential variable. Programs with existential variables in negated goals can be transformed into equivalent programs without. For instance the last rule can be re-written as:
   print_nice_people(`everybody is nice') <- ~someonenasty.
   someonenasty <- nasty(Y).
This re-writing defines the evaluation used by the system.

Negation: safety rules

The appearence of variables in negated goals does not make them safe. For instance, Y in the following rule is always unsafe ( the safety of X depends on the export used)

     p(X)  <-  Y > X, ~r(X, Y).
An unbound variable appearing in a negated goals can never be used in later goals of the rule. For instance
    print_nasty_people(X) <- ~nice(X),  person(X).

This rule will not compile. Thus, the order of goals in the rules must be switched.

example8.prg
Previous: Negation
Table of Contents Next: Complex Terms and Lists    Stratification

We cannot use negation in a recursive definition. We say that such a program is non-stratified.

Example: A non-stratified program, see Predicate Connection Graph.

even(0).
even(Y) <- ~even(X), Y = X + 1.
The correct way to specify this program is:
int(1).
int(Y) <- int(X), Y=X+1.
odd(X) <- int(X), X mod 2 ~= 0.
even(X) <- int(X), ~odd(X).
Now the negation is out of the recursion.



Next Page Top of Page
Carlo Zaniolo, 1997