From d1397cb10bdbd45d3e40f64111408b9a7f0e0cf4 Mon Sep 17 00:00:00 2001 From: Lachnitt Date: Tue, 9 Nov 2021 14:10:32 -0800 Subject: [PATCH] [proofs] Alethe: Translate Equality rules (#7605) Implementation of the translation of SYMM, TRANS and CONG rules into the Alethe calculus. Co-authored-by: Haniel Barbosa --- src/proof/alethe/alethe_post_processor.cpp | 89 ++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/src/proof/alethe/alethe_post_processor.cpp b/src/proof/alethe/alethe_post_processor.cpp index ff17941e9..c60b53ed7 100644 --- a/src/proof/alethe/alethe_post_processor.cpp +++ b/src/proof/alethe/alethe_post_processor.cpp @@ -1162,6 +1162,95 @@ bool AletheProofPostprocessCallback::update(Node res, && addAletheStepFromOr( AletheRule::DUPLICATED_LITERALS, res, {vp4}, {}, *cdp); } + //================================================= Equality rules + // The following rules are all translated according to the singleton + // pattern. + case PfRule::REFL: + { + return addAletheStep(AletheRule::REFL, + res, + nm->mkNode(kind::SEXPR, d_cl, res), + children, + {}, + *cdp); + } + case PfRule::SYMM: + { + return addAletheStep( + res.getKind() == kind::NOT ? AletheRule::NOT_SYMM : AletheRule::SYMM, + res, + nm->mkNode(kind::SEXPR, d_cl, res), + children, + {}, + *cdp); + } + case PfRule::TRANS: + { + return addAletheStep(AletheRule::TRANS, + res, + nm->mkNode(kind::SEXPR, d_cl, res), + children, + {}, + *cdp); + } + // ======== Congruence + // In the case that the kind of the function symbol f? is FORALL or + // EXISTS, the cong rule needs to be converted into a bind rule. The first + // n children will be refl rules, e.g. (= (v0 Int) (v0 Int)). + // + // Let t1 = (BOUND_VARIABLE LIST (v1 A1) ... (vn An)) and s1 = + // (BOUND_VARIABLE LIST (v1 A1) ... (vn vn)). + // + // ----- REFL ... ----- REFL + // VP1 VPn P2 + // --------------------------------------- bind, + // ((:= (v1 A1) v1) ... + // (:= (vn An) vn)) + // (cl (= (forall ((v1 A1)...(vn An)) t2) + // (forall ((v1 B1)...(vn Bn)) s2)))** + // + // VPi: (cl (= vi vi))* + // + // * the corresponding proof node is (or (= vi vi)) + // + // Otherwise, the rule follows the singleton pattern, i.e.: + // + // P1 ... Pn + // -------------------------------------------------------- cong + // (cl (= ( f? t1 ... tn) ( f? s1 ... sn)))** + // + // ** the corresponding proof node is (= ( f? t1 ... tn) ( f? + // s1 ... sn)) + case PfRule::CONG: + { + if (res[0].isClosure()) + { + std::vector vpis; + bool success = true; + for (size_t i = 0, size = children[0][0].getNumChildren(); i < size; + i++) + { + Node vpi = children[0][0][i].eqNode(children[0][1][i]); + new_args.push_back(vpi); + vpis.push_back(nm->mkNode(kind::SEXPR, d_cl, vpi)); + success &= addAletheStep(AletheRule::REFL, vpi, vpi, {}, {}, *cdp); + } + vpis.push_back(children[1]); + return success + && addAletheStep(AletheRule::ANCHOR_BIND, + res, + nm->mkNode(kind::SEXPR, d_cl, res), + vpis, + new_args, + *cdp); + } + return addAletheStep(AletheRule::CONG, + res, + nm->mkNode(kind::SEXPR, d_cl, res), + children, + {}, + *cdp); + } default: { return addAletheStep(AletheRule::UNDEFINED, -- 2.30.2