type ritem = { size: int, (* the size of the equivalence class *)
class: Argo_Term.term list, (* the equivalence class as a list of distinct terms *)
occs: Argo_Term.term list, (* a list of all application terms in which members of
the equivalence class occur either as function or as argument *)
neqs: (Argo_Term.term * eq) list, (* a list of terms from disjoint equivalence classes, foreachtermofthislistthereisacertificateofanegatedequalitythatis
required to explain why the equivalence classes are disjoint *)
atoms: atoms} (* the atoms of the representative *)
type repr = Argo_Term.term Argo_Termtab.table type rdata = ritem Argo_Termtab.table type apps = Argo_Term.term Argo_Term2tab.table type trace = (Argo_Term.term * eq) Argo_Termtab.table
type context = {
repr: repr, (* a table mapping terms to their representatives *)
rdata: rdata, (* a table mapping representatives to their ritems *)
apps: apps, (* a table mapping a function and an argument to their application *)
trace: trace, (* the proof forest used to trace assumed and implied equalities *)
prf: Argo_Proof.context, (* the proof context *)
back: (repr * rdata * apps * trace) list} (* backtracking information *)
val context =
mk_context Argo_Termtab.empty Argo_Termtab.empty Argo_Term2tab.empty Argo_Termtab.empty
Argo_Proof.cc_context []
fun repr_of repr t = the_default t (Argo_Termtab.lookup repr t) fun repr_of' ({repr, ...}: context) = repr_of repr fun put_repr t r = Argo_Termtab.update (t, r)
fun mk_ritem size class occs neqs atoms: ritem =
{size=size, class=class, occs=occs, neqs=neqs, atoms=atoms}
fun as_ritem t = mk_ritem 1 [t] [] [] (Eqs []) fun as_pred_ritem t = mk_ritem 1 [t] [] [] (Preds [t]) fun gen_ritem_of mk rdata r = the_default (mk r) (Argo_Termtab.lookup rdata r) fun ritem_of rdata = gen_ritem_of as_ritem rdata fun ritem_of_pred rdata = gen_ritem_of as_pred_ritem rdata fun ritem_of' ({rdata, ...}: context) = ritem_of rdata fun put_ritem r ri = Argo_Termtab.update (r, ri)
fun add_occ r occ = Argo_Termtab.map_default (r, as_ritem r)
(fn {size, class, occs, neqs, atoms}: ritem => mk_ritem size class (occ :: occs) neqs atoms)
fun put_atoms atoms ({size, class, occs, neqs, ...}: ritem) = mk_ritem size class occs neqs atoms
fun add_eq_atom r atom = Argo_Termtab.map_default (r, as_ritem r)
(fn ri as {atoms=Eqs atoms, ...}: ritem => put_atoms (Eqs (atom :: atoms)) ri
| ri => put_atoms (Eqs [atom]) ri)
fun lookup_app apps tp = Argo_Term2tab.lookup apps tp fun put_app tp app = Argo_Term2tab.update_new (tp, app)
fun mk_eq_proof trace t1 t2 lits prf = if Argo_Term.eq_term (t1, t2) then (lits, Argo_Proof.mk_refl t1 prf) else let val root = common_ancestor trace t1 t2 val (lits, (p1, prf)) = trans_proof I I trace t1 root lits prf val (lits, (p2, prf)) = trans_proof swap symm trace t2 root lits prf in (lits, Argo_Proof.mk_trans p1 p2 prf) end
and trans_proof sw sy trace t root lits prf = if Argo_Term.eq_term (t, root) then (lits, Argo_Proof.mk_refl t prf) else
(case Argo_Termtab.lookup trace t of
NONE => raise Fail "bad trace"
| SOME (t', eq) => let val (lits, (p1, prf)) = proof_step trace (sy eq) lits prf val (lits, (p2, prf)) = trans_proof sw sy trace t' root lits prf in (lits, uncurry Argo_Proof.mk_trans (sw (p1, p2)) prf) end)
and proof_step _ (Flat (cert, _)) lits prf = proof_of cert lits prf
| proof_step trace (Cong tp) lits prf = let val ((t1, t2), (u1, u2)) = apply2 dest_app tp val (lits, (p1, prf)) = mk_eq_proof trace t1 u1 lits prf val (lits, (p2, prf)) = mk_eq_proof trace t2 u2 lits prf in (lits, Argo_Proof.mk_cong p1 p2 prf) end
| proof_step trace (Symm eq) lits prf =
proof_step trace eq lits prf ||> uncurry Argo_Proof.mk_symm
fun with_max_class f (rp as (r1, r2)) (rip as (ri1: ritem, ri2: ritem)) eq = if #size ri1 >= #size ri2 then f rp rip eq else f (r2, r1) (ri2, ri1) (symm eq)
(* commentmissing
*)
fun propagate ([], ls, cx) = (rev ls, cx)
| propagate (eq :: eqs, ls, cx) = letval rp = apply2 (repr_of' cx) (dest_eq eq) in if Argo_Term.eq_term rp then propagate (eqs, ls, cx) else propagate (with_max_class check_join rp (apply2 (ritem_of' cx) rp) eq (eqs, ls, cx)) end
fun without lit (lits, cx) = (Argo_Common.Implied (remove Argo_Lit.eq_lit lit lits), cx)
fun flat_merge (lp as (lit, _)) eq cx = without lit (propagate ([Flat (lp, eq)], [], cx)) handle CONFLICT (cls, cx) => (Argo_Common.Conflict cls, cx)
(* commentmissing
*)
fun app_merge app tp (cx as {repr, rdata, apps, trace, prf, back}: context) = letval rp as (r1, r2) = apply2 (repr_of repr) tp in
(case lookup_app apps rp of
SOME app' =>
(case propagate ([Cong (app, app')], [], cx) of
([], cx) => cx
| _ => raise Fail "bad application merge")
| NONE => letval rdata = add_occ r1 app (add_occ r2 app rdata) in mk_context repr rdata (put_app rp app apps) trace prf back end) end
fun note_neq eq (r1, r2) (t1, t2) ({repr, rdata, apps, trace, prf, back}: context) = let val {size=size1, class=class1, occs=occs1, neqs=neqs1, atoms=atoms1}: ritem = ritem_of rdata r1 val {size=size2, class=class2, occs=occs2, neqs=neqs2, atoms=atoms2}: ritem = ritem_of rdata r2
fun add r (Eqs eqs) ls = fold (add_implied Argo_Lit.Neg repr rdata r []) eqs ([], ls) |>> Eqs
| add _ _ _ = raise Fail "bad negated equality between predicates" val ((atoms1, atoms2), ls) = [] |> add r2 atoms1 ||>> add r1 atoms2 val ri1 = mk_ritem size1 class1 occs1 ((t2, eq) :: neqs1) atoms1 val ri2 = mk_ritem size2 class2 occs2 ((t1, symm eq) :: neqs2) atoms2 in (ls, mk_context repr (put_ritem r1 ri1 (put_ritem r2 ri2 rdata)) apps trace prf back) end
fun flat_neq (lp as (lit, _)) (tp as (t1, t2)) cx = letval rp = apply2 (repr_of' cx) tp in if Argo_Term.eq_term rp then letval (cls, cx) = explain_eq (Argo_Lit.negate lit) t1 t2 cx in (Argo_Common.Conflict cls, cx) end else without lit (note_neq (Flat (lp, tp)) rp tp cx) end
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.