module Unification:term unificationsig
..end
This modules provides the basic unification functions for terms and literals.
For an explanation of offsets, p_preserving, recompute see Subst
.
typeterm =
Term.term
typeliteral =
Term.literal
typeclause =
Term.clause
typebinding =
Subst.binding
typesubst =
Subst.subst
exception UNIFICATION_FAIL
val is_term_generalization : ?p_preserving:bool -> term -> term -> bool
val is_term_instance : ?p_preserving:bool -> term -> term -> bool
val is_literal_instance : ?p_preserving:bool -> literal -> literal -> bool
val match_terms : recompute:bool ->
?p_preserving:bool ->
term -> int -> term -> int -> subst
match_terms term1 offset1 term2 offset2
returns a most general substitution which applied to term1 offset1
produces term2
.
raises Unification.UNIFICATION_FAIL
val match_literals : recompute:bool ->
?p_preserving:bool ->
literal -> int -> literal -> int -> subst
Unification.match_terms
over literals.val are_terms_unifiable : ?p_preserving:bool -> term -> term -> bool
val unify_terms : recompute:bool ->
?p_preserving:bool ->
term -> int -> term -> int -> subst
unify_terms term1 offset1 term2 offset2
returns a most general substitution which applied to term1 offset1
or term2 offset2
produces the same term.
prefers to bind universal variables to parametric ones
instead of vice versa (see Admissible
).
raises Unification.UNIFICATION_FAIL
if no unifier exists.
val unify_terms_ : recompute:bool ->
?p_preserving:bool ->
subst ->
term -> int -> term -> int -> subst
unify_terms
, but extends the given substitution.val unify_literals : recompute:bool ->
?p_preserving:bool ->
literal -> int -> literal -> int -> subst
Unification.unify_terms
over literals.val unify_literals_ : recompute:bool ->
?p_preserving:bool ->
subst ->
literal -> int -> literal -> int -> subst
unify_literals
, but extends the given substitution.val unify_constraints : recompute:bool ->
((literal * int) * (literal * int)) list ->
subst
(p(x), 1), (q(f(x)), 2)
yields [ 1:x -> 2:f(x) ]
val unify_constraints' : recompute:bool ->
((literal * int) * (literal * int)) list ->
Subst.hash_subst
hash_subst
.Allows to unifiy two literal lists (or clauses) separately literal pair by literal pair and afterwords combining the computed substitution, instead of incrementally computing one substitution.
Also used in substitution trees.
Faster if the first substitution is the larger substitution.
val match_substs : recompute:bool ->
?p_preserving:bool ->
int -> subst -> subst -> subst
match_substs subsuming_offset subst1 subst2
merges subst1
and subst2
.
Terms with subsuming_offset
have been matched to other terms,
and the resulting substitutions are now to be merged.
If a variable is bound to different terms in subst1 and subst2 the bound terms are unified. I.e. if
subsuming_offset
they are unified (Unification.unify_terms
)subsuming_offset
it is matched
(Unification.match_terms
) to the othersubsuming_offset
the substitutions are not matcheable
and Unification.UNIFICATION_FAIL
is raised.val unify_substs : recompute:bool ->
?p_preserving:bool ->
subst -> subst -> subst
match_substs subsuming_offset subst1 subst2
merges subst1
and subst2
.
If a variable is bound to different terms in subst1 and subst2
the bound terms are unified (Unification.unify_terms
).
if x -> y
and y -> x
have to be merged one is dropped
and the other kept, i.e. this is not considered to be a cyclic binding.
Examples:
x -> a
and x -> b
are not mergeable. x -> g(y)
and y -> a
becomes x -> g(y); y -> a
. x -> g(y)
and x -> g(a)
becomes x -> g(y); y -> a
. x -> y
and y -> x
becomes x -> y
or y -> x
.Unification.UNIFICATION_FAIL
on not mergeable substitutions.val unify_substs_shallow : subst -> subst -> unit
Unification.UNIFICATION_FAIL
if that fails.val merge_substs : subst -> subst -> subst
merge_substs subst1 subst2
merges subst1
and subst2
by adding all bindings into one substitution.
if a variable is bound in both substitutions,
Unification.UNIFICATION_FAIL
is raised if it is bound to different terms,
otherwise only one of the two identical bindings is kept.
no other consistency checks are performed,
that is for example cycles may be introduced.
val subsumes : clause -> clause -> bool
e.g. { p(a) }
subsumes { p(x), p(a) }
.
this implies that the subsuming clause has at most as many literal as the subsumed clause. despite of this, no prefiltering is done at all, subsumption is strictly done in an exponential trial and error way.
the clauses are subsumed to be universal,
i.e. unification is not done p-preserving.
val condense : clause -> clause
e.g. { p(x), p(a) }
is condensed to { p(a) }
.
worst case complexity is a linear number of subsumption tests.