Non-Frame Predicates

Sometimes a property does not seem to belong to any particular class. This happens especially when we’re comparing two objects of the same type, and both objects have equal status, i.e. neither can reasonably be picked as the subject of the property. For example, suppose we want to find the oldest of two people or find the distance between two cities, we might use non-frame predicates like:

oldest(?person1, ?person2, ?oldest)
distance(?city1, ?city2, ?distance)

These can be defined by rules as usual,

@!{OldestPersonRule1}
oldest(?person1, ?person2, ?age1) :-
  ?person1 [ age -> ?age1 ],
  ?person2 [ age -> ?age2 ],
  ?age1 >= ?age2.
@!{OldestPersonRule2}
oldest(?person1, ?person2, ?age2) :-
  ?person1 [ age -> ?age1 ],
  ?person2 [ age -> ?age2 ],
  ?age2 > ?age1.

Here we arbitrarily award a draw to the first person.

However, these situations are rare. In most cases, frames should be used. Using frames has two advantages: a more uniform style of encoding, and we can give the correct types of arguments in schema frames (there is no way to provide a schema for non-frame predicates).

For the cases above, we could use the frame versions:

?person1 [ olderThan(?person2) ]
?city1 [ distanceTo(?city2) -> ?distance ]