@ -741,34 +741,45 @@ let remove_absent_xs ks q =
let rec simplify_ us rev_xss q =
let rec simplify_ us rev_xss q =
[ % Trace . call fun { pf } -> pf " %a@ %a " pp_vss ( List . rev rev_xss ) pp_raw q ]
[ % Trace . call fun { pf } -> pf " %a@ %a " pp_vss ( List . rev rev_xss ) pp_raw q ]
;
;
let rev_xss = q . xs :: rev_xss in
(* bind existentials *)
let xs , q = bind_exists ~ wrt : emp . us q in
let rev_xss = xs :: rev_xss in
(* recursively simplify subformulas *)
(* recursively simplify subformulas *)
let q =
let q =
exists q . xs
starN
( starN
( { q with djns = [] }
( { q with us = Var . Set . union q . us q . xs ; xs = emp . xs ; djns = [] }
:: List . map q . djns ~ f : ( fun djn ->
:: List . map q . djns ~ f : ( fun djn ->
orN ( List . map djn ~ f : ( fun sjn -> simplify_ us rev_xss sjn ) ) )
orN ( List . map djn ~ f : ( fun sjn -> simplify_ us rev_xss sjn ) ) )
) )
)
in
in
(* try to solve equations in ctx for variables in xss *)
(* try to solve equations in ctx for variables in xss *)
let subst = Context . solve_for_vars ( us :: List . rev rev_xss ) q . ctx in
let subst = Context . solve_for_vars ( us :: List . rev rev_xss ) q . ctx in
let removed , q =
(* simplification can reveal inconsistency *)
(* simplification can reveal inconsistency *)
( if is_false q then false _ q . us
if is_false q then ( Var . Set . empty , false _ q . us )
else if Context . Subst . is_empty subst then q
else if Context . Subst . is_empty subst then ( Var . Set . empty , q )
else
else
(* normalize wrt solutions *)
(* normalize wrt solutions *)
let q = norm subst q in
let q = norm subst q in
(* reconjoin only non-redundant equations *)
(* reconjoin only non-redundant equations *)
let _ , ctx' =
Context . apply_subst
( Var . Set . union us ( Var . Set . union_list rev_xss ) )
subst q . ctx
in
let removed =
let removed =
Var . Set . diff
Var . Set . diff
( Var . Set . union_list rev_xss )
( Var . Set . union_list rev_xss )
( fv ~ ignore_ctx : () ( elim_exists q . xs q ) )
( Var . Set . union ( Context . fv ctx' )
( fv ~ ignore_ctx : () ( elim_exists q . xs q ) ) )
in
in
let keep , removed , _ = Context . Subst . partition_valid removed subst in
let keep , removed , _ = Context . Subst . partition_valid removed subst in
let q = and_subst keep q in
( removed , and_subst keep q )
in
(* re-quantify existentials *)
let q = exists xs q in
(* remove the eliminated variables from xs and subformulas' us *)
(* remove the eliminated variables from xs and subformulas' us *)
remove_absent_xs removed q )
remove_absent_xs removed q
| >
| >
[ % Trace . retn fun { pf } q' ->
[ % Trace . retn fun { pf } q' ->
pf " %a@ %a " Context . Subst . pp subst pp_raw q' ;
pf " %a@ %a " Context . Subst . pp subst pp_raw q' ;