[proofs] Alethe: Translate THEORY_REWRITE (#7236)
authorLachnitt <lachnitt@stanford.edu>
Thu, 23 Sep 2021 22:08:31 +0000 (15:08 -0700)
committerGitHub <noreply@github.com>
Thu, 23 Sep 2021 22:08:31 +0000 (22:08 +0000)
Implementation of the translation of THEORY_REWRITE rules into the Alethe calculus.

Co-authored-by: Haniel Barbosa <hanielbbarbosa@gmail.com>
src/proof/alethe/alethe_post_processor.cpp
src/theory/builtin/proof_checker.cpp

index 9b94175fa292cd53ec4302db2e4300b100993129..97afbdab0a22b26f60dfbd03dc73491f44098376 100644 (file)
@@ -19,6 +19,7 @@
 #include "proof/proof.h"
 #include "proof/proof_checker.h"
 #include "util/rational.h"
+#include "theory/builtin/proof_checker.h"
 
 namespace cvc5 {
 
@@ -149,7 +150,6 @@ bool AletheProofPostprocessCallback::update(Node res,
                                children,
                                sanitized_args,
                                *cdp);
-
       Node andNode, vp3;
       if (args.size() == 1)
       {
@@ -239,6 +239,171 @@ bool AletheProofPostprocessCallback::update(Node res,
 
       return success;
     }
+    // The rule is translated according to the theory id tid and the outermost
+    // connective of the first term in the conclusion F, since F always has the
+    // form (= t1 t2) where t1 is the term being rewritten. This is not an exact
+    // translation but should work in most cases.
+    //
+    // E.g. if F is (= (* 0 d) 0) and tid = THEORY_ARITH, then prod_simplify
+    // is correctly guessed as the rule.
+    case PfRule::THEORY_REWRITE:
+    {
+      AletheRule vrule = AletheRule::UNDEFINED;
+      Node t = res[0];
+
+      theory::TheoryId tid;
+      if (!theory::builtin::BuiltinProofRuleChecker::getTheoryId(args[1], tid))
+      {
+        return addAletheStep(
+            vrule, res, nm->mkNode(kind::SEXPR, d_cl, res), children, {}, *cdp);
+      }
+      switch (tid)
+      {
+        case theory::TheoryId::THEORY_BUILTIN:
+        {
+          switch (t.getKind())
+          {
+            case kind::ITE:
+            {
+              vrule = AletheRule::ITE_SIMPLIFY;
+              break;
+            }
+            case kind::EQUAL:
+            {
+              vrule = AletheRule::EQ_SIMPLIFY;
+              break;
+            }
+            case kind::AND:
+            {
+              vrule = AletheRule::AND_SIMPLIFY;
+              break;
+            }
+            case kind::OR:
+            {
+              vrule = AletheRule::OR_SIMPLIFY;
+              break;
+            }
+            case kind::NOT:
+            {
+              vrule = AletheRule::NOT_SIMPLIFY;
+              break;
+            }
+            case kind::IMPLIES:
+            {
+              vrule = AletheRule::IMPLIES_SIMPLIFY;
+              break;
+            }
+            case kind::WITNESS:
+            {
+              vrule = AletheRule::QNT_SIMPLIFY;
+              break;
+            }
+            default:
+            {
+              // In this case the rule is undefined
+            }
+          }
+          break;
+        }
+        case theory::TheoryId::THEORY_BOOL:
+        {
+          vrule = AletheRule::BOOL_SIMPLIFY;
+          break;
+        }
+        case theory::TheoryId::THEORY_UF:
+        {
+          if (t.getKind() == kind::EQUAL)
+          {
+            // A lot of these seem to be symmetry rules but not all...
+            vrule = AletheRule::EQUIV_SIMPLIFY;
+          }
+          break;
+        }
+        case theory::TheoryId::THEORY_ARITH:
+        {
+          switch (t.getKind())
+          {
+            case kind::DIVISION:
+            {
+              vrule = AletheRule::DIV_SIMPLIFY;
+              break;
+            }
+            case kind::PRODUCT:
+            {
+              vrule = AletheRule::PROD_SIMPLIFY;
+              break;
+            }
+            case kind::MINUS:
+            {
+              vrule = AletheRule::MINUS_SIMPLIFY;
+              break;
+            }
+            case kind::UMINUS:
+            {
+              vrule = AletheRule::UNARY_MINUS_SIMPLIFY;
+              break;
+            }
+            case kind::PLUS:
+            {
+              vrule = AletheRule::SUM_SIMPLIFY;
+              break;
+            }
+            case kind::MULT:
+            {
+              vrule = AletheRule::PROD_SIMPLIFY;
+              break;
+            }
+            case kind::EQUAL:
+            {
+              vrule = AletheRule::EQUIV_SIMPLIFY;
+              break;
+            }
+            case kind::LT:
+            {
+              [[fallthrough]];
+            }
+            case kind::GT:
+            {
+              [[fallthrough]];
+            }
+            case kind::GEQ:
+            {
+              [[fallthrough]];
+            }
+            case kind::LEQ:
+            {
+              vrule = AletheRule::COMP_SIMPLIFY;
+              break;
+            }
+            case kind::CAST_TO_REAL:
+            {
+              return addAletheStep(AletheRule::LA_GENERIC,
+                                   res,
+                                   nm->mkNode(kind::SEXPR, d_cl, res),
+                                   children,
+                                   {nm->mkConst(Rational(1))},
+                                   *cdp);
+            }
+            default:
+            {
+              // In this case the rule is undefined
+            }
+          }
+          break;
+        }
+        case theory::TheoryId::THEORY_QUANTIFIERS:
+        {
+          vrule = AletheRule::QUANTIFIER_SIMPLIFY;
+          break;
+        }
+        default:
+        {
+          // In this case the rule is undefined
+        };
+      }
+      return addAletheStep(
+          vrule, res, nm->mkNode(kind::SEXPR, d_cl, res), children, {}, *cdp);
+    }
     default:
     {
       return addAletheStep(AletheRule::UNDEFINED,
index 1309a05f948d7e179519a05e9c87251b5dd0c38b..d5b856456f9b76077a808731f688119d7016b220 100644 (file)
@@ -57,6 +57,7 @@ void BuiltinProofRuleChecker::registerTo(ProofChecker* pc)
   pc->registerTrustedChecker(PfRule::TRUST_SUBS_MAP, this, 1);
   pc->registerTrustedChecker(PfRule::TRUST_SUBS_EQ, this, 3);
   pc->registerTrustedChecker(PfRule::THEORY_INFERENCE, this, 3);
+  pc->registerChecker(PfRule::ALETHE_RULE, this);
 }
 
 Node BuiltinProofRuleChecker::applySubstitutionRewrite(