let rec process fct (s, p) =
Is.initialize fct s p;
eval ();
assert(G.is_empty !Infsys.g);
Is.finalize ()
and eval () =
if G.is_empty !Infsys.g then
Is.normalize ()
else
begin
eval1 ();
eval ()
end
and eval1 () =
try
let ((atm, rho) as fct) = G.get !Infsys.g in
(match Atom.atom_of atm with
| Atom.TT ->
()
| Atom.FF ->
raise(Jst.Inconsistent(rho))
| Atom.Equal(a, b) ->
let e = Fact.Equal.make a b rho in
(match Fact.Equal.status e with
| Term.Variable -> merge_v e
| Term.Pure(i) -> merge_i i e
| Term.Mixed(i, a) -> abstract fct i a)
| Atom.Diseq(a, b) ->
let d = Fact.Diseq.make a b rho in
(match Fact.Diseq.status d with
| Term.Variable -> dismerge_v d
| Term.Pure(i) -> dismerge_i i d
| Term.Mixed(i, a) -> abstract fct i a)
| Atom.Nonneg(a) ->
let nn = Fact.Nonneg.make a rho in
(match Fact.Nonneg.status nn with
| Term.Variable -> nonneg_la nn
| Term.Pure(i) when i = Th.la -> nonneg_la nn
| Term.Pure(i) -> abstract fct i (Fact.Nonneg.term_of nn)
| Term.Mixed(i, a) -> abstract fct i a)
| Atom.Pos(a) ->
let pp = Fact.Pos.make a rho in
(match Fact.Pos.status pp with
| Term.Variable -> pos_la pp
| Term.Pure(i) when i = Th.la -> pos_la pp
| Term.Pure(i) -> abstract fct i (Fact.Pos.term_of pp)
| Term.Mixed(i, a) -> abstract fct i a))
with
Not_found -> ()
and merge_v e =
assert(Fact.Equal.is_var e);
Partition.merge !Infsys.p e;
propagate ()
and merge_i i e =
assert(Fact.Equal.is_pure i e);
Is.merge i e;
propagate ()
and abstract fct i a =
G.put fct !Infsys.g;
Is.abstract i a;
propagate ()
and propagate () =
try
let e = Partition.fresh_equal !Infsys.p in
Is.propagate e;
propagate ()
with
Not_found ->
(try
let d = Partition.fresh_diseq !Infsys.p in
Is.propagate_diseq d;
propagate ()
with
Not_found -> ())
and dismerge_v d =
assert(Fact.Diseq.is_var d);
Partition.dismerge !Infsys.p d;
propagate ()
and dismerge_i i d =
assert(Fact.Diseq.is_pure i d);
Is.dismerge i d;
propagate ()
and nonneg_la nn =
assert(Fact.Nonneg.is_pure Th.la nn);
Is.nonneg nn;
propagate ()
and pos_la pp =
assert(Fact.Pos.is_pure Th.la pp);
Is.pos pp;
propagate ()
and is_diseq_complete ((s, p) as cfg) a b =
let d = (Atom.mk_diseq (a, b), Jst.dep0) in
try
let _ = process d cfg in
None
with
Jst.Inconsistent(rho) -> Some(rho)