Examples:
op and:(t => truth ×t => truth) => truth | |||||||
var x:t; P,Q:t => logical | |||||||
axiom and(P,Q)(x) <=> P(x) /\ Q(x) |
In (an encoding of) a temporal logic, we would have a sort time, and truth values are predicates time => logical. Then a predicate everytime:(time => logical) => logical could be defined as everytime(p) <=> forall t:time.p(t)
Another advantage is that user-defined logical connectives become possible:
op xor:(truth ×truth) => truth | |||||||
var x,y:truth | |||||||
axioms xor(x,y) <=> (¬x <=> y) | |||||||
...xor(phi,psi) ... |
Alternatives:
With this, we loose the possibility to have user-defined logical connectives in a convenient manner. We have to write:
op xor:pred(pred() ×pred()) | |||||||
var P,Q:pred() | |||||||
axioms xor(P,Q) <=> (¬P() <=> Q()) | |||||||
...xor(\x:().phi,\x:().psi) ... |
Then, predicate application is defined as follows: The predicate term is always defined by the above restriction of the type system. If the argument term is undefined, yield the canonical value, otherwise, apply the predicate.
This alternative is a s which still captures all practically needed cases. But since the restriction rather adds complexity instead of reducing complexity, we do not find it so useful.