LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/uf - eq_proof.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 1 100.0 %
Date: 2025-02-09 13:32:29 Functions: 1 1 100.0 %
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * Top contributors (to current version):
       3                 :            :  *   Haniel Barbosa, Mathias Preiner
       4                 :            :  *
       5                 :            :  * This file is part of the cvc5 project.
       6                 :            :  *
       7                 :            :  * Copyright (c) 2009-2025 by the authors listed in the file AUTHORS
       8                 :            :  * in the top-level source directory and their institutional affiliations.
       9                 :            :  * All rights reserved.  See the file COPYING in the top-level source
      10                 :            :  * directory for licensing information.
      11                 :            :  * ****************************************************************************
      12                 :            :  *
      13                 :            :  * A proof as produced by the equality engine.
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "cvc5_private.h"
      17                 :            : #include "expr/node.h"
      18                 :            : #include "theory/uf/equality_engine_types.h"
      19                 :            : 
      20                 :            : namespace cvc5::internal {
      21                 :            : 
      22                 :            : class CDProof;
      23                 :            : 
      24                 :            : namespace theory {
      25                 :            : namespace eq {
      26                 :            : 
      27                 :            : /**
      28                 :            :  * An equality proof.
      29                 :            :  *
      30                 :            :  * This represents the reasoning performed by the Equality Engine to derive
      31                 :            :  * facts, represented in terms of the rules in MergeReasonType. Each proof step
      32                 :            :  * is annotated with the rule id, the conclusion node and a vector of proofs of
      33                 :            :  * the rule's premises.
      34                 :            :  **/
      35                 :            : class EqProof
      36                 :            : {
      37                 :            :  public:
      38                 :    7408740 :   EqProof() : d_id(MERGED_THROUGH_REFLEXIVITY) {}
      39                 :            :   /** The proof rule for concluding d_node */
      40                 :            :   MergeReasonType d_id;
      41                 :            :   /** The conclusion of this EqProof */
      42                 :            :   Node d_node;
      43                 :            :   /** The proofs of the premises for deriving d_node with d_id */
      44                 :            :   std::vector<std::shared_ptr<EqProof>> d_children;
      45                 :            :   /**
      46                 :            :    * Debug print this proof on debug trace c with tabulation tb.
      47                 :            :    */
      48                 :            :   void debug_print(const char* c, unsigned tb = 0) const;
      49                 :            :   /**
      50                 :            :    * Debug print this proof on output stream os with tabulation tb.
      51                 :            :    */
      52                 :            :   void debug_print(std::ostream& os, unsigned tb = 0) const;
      53                 :            : 
      54                 :            :   /** Add to proof
      55                 :            :    *
      56                 :            :    * Converts EqProof into ProofNode via a series of steps to be stored in
      57                 :            :    * CDProof* p.
      58                 :            :    *
      59                 :            :    * This method can be seen as a best-effort solution until the EqualityEngine
      60                 :            :    * is updated to produce ProofNodes directly, if ever. Note that since the
      61                 :            :    * original EqProof steps can be coarse-grained (e.g. without proper order,
      62                 :            :    * implicit inferences related to disequelaties) and are phrased over curried
      63                 :            :    * terms, the transformation requires significant, although cheap (mostly
      64                 :            :    * linear on the DAG-size of EqProof), post-processing.
      65                 :            :    *
      66                 :            :    * An important invariant of the resulting ProofNode is that neither its
      67                 :            :    * assumptions nor its conclusion are predicate equalities, i.e. of the form
      68                 :            :    * (= t true/false), modulo symmetry. This is so that users of the converted
      69                 :            :    * ProofNode don't need to do case analysis on whether assumptions/conclusion
      70                 :            :    * are either t or (= t true/false).
      71                 :            :    *
      72                 :            :    * @param p a pointer to a CDProof to store the conversion of this EqProof
      73                 :            :    * @return the node that is the conclusion of the proof as added to p.
      74                 :            :    */
      75                 :            :   Node addToProof(CDProof* p) const;
      76                 :            : 
      77                 :            :  private:
      78                 :            :   /**
      79                 :            :    * As above, but with a cache of previously processed nodes and their results
      80                 :            :    * (for DAG traversal). The caching is in terms of the original conclusions of
      81                 :            :    * EqProof.
      82                 :            :    *
      83                 :            :    * @param p a pointer to a CDProof to store the conversion of this EqProof
      84                 :            :    * @param visited a cache of the original EqProof conclusions and the
      85                 :            :    * resulting conclusion after conversion.
      86                 :            :    * @param assumptions the assumptions of the original EqProof (and their
      87                 :            :    * variations in terms of symmetry and conversion to/from predicate
      88                 :            :    * equalities)
      89                 :            :    * @return the node that is the conclusion of the proof as added to p.
      90                 :            :    */
      91                 :            :   Node addToProof(CDProof* p,
      92                 :            :                   std::unordered_map<Node, Node>& visited,
      93                 :            :                   std::unordered_set<Node>& assumptions) const;
      94                 :            : 
      95                 :            :   /** Removes all reflexivity steps, i.e. (= t t), from premises. */
      96                 :            :   void cleanReflPremises(std::vector<Node>& premises) const;
      97                 :            : 
      98                 :            :   /** Expand coarse-grained transitivity steps for disequalities
      99                 :            :    *
     100                 :            :    * Currently the equality engine can represent disequality reasoning in a
     101                 :            :    * rather coarse-grained manner with EqProof. This is always the case when the
     102                 :            :    * transitivity step contains a disequality, (= (= t t') false) or its
     103                 :            :    * symmetric, as a premise.
     104                 :            :    *
     105                 :            :    * There are two cases. In the simplest one the general shape of the EqProof
     106                 :            :    * is
     107                 :            :    *  (= t1 t2) (= t3 t2) (= (t1 t3) false)
     108                 :            :    *  ------------------------------------- EQP::TR
     109                 :            :    *             false = true
     110                 :            :    *
     111                 :            :    * which is expanded into
     112                 :            :    *                                          (= t3 t2)
     113                 :            :    *                                          --------- SYMM
     114                 :            :    *                                (= t1 t2) (= t2 t3)
     115                 :            :    *                                ------------------- TRANS
     116                 :            :    *   (= (= t1 t3) false)                (= t1 t3)
     117                 :            :    *  --------------------- SYMM    ------------------ TRUE_INTRO
     118                 :            :    *   (= false (= t1 t3))         (= (= t1 t3) true)
     119                 :            :    *  ----------------------------------------------- TRANS
     120                 :            :    *             false = true
     121                 :            :    *
     122                 :            :    * by explicitly adding the transitivity step for inferring (= t1 t3) and its
     123                 :            :    * predicate equality. Note that we differentiate (from now on) the EqProof
     124                 :            :    * rules ids from those of ProofRule by adding the prefix EQP:: to the former.
     125                 :            :    *
     126                 :            :    * In the other case, the general shape of the EqProof is
     127                 :            :    *
     128                 :            :    *  (= (= t1 t2) false) (= t1 x1) ... (= xn t3) (= t2 y1) ... (= ym t4)
     129                 :            :    * ------------------------------------------------------------------- EQP::TR
     130                 :            :    *         (= (= t4 t3) false)
     131                 :            :    *
     132                 :            :    * which is converted into
     133                 :            :    *
     134                 :            :    *   (= t1 x1) ... (= xn t3)      (= t2 y1) ... (= ym t4)
     135                 :            :    *  ------------------------ TR  ------------------------ TR
     136                 :            :    *   (= t1 t3)                    (= t2 t4)
     137                 :            :    *  ----------- SYMM             ----------- SYMM
     138                 :            :    *   (= t3 t1)                    (= t4 t2)
     139                 :            :    *  ---------------------------------------- CONG
     140                 :            :    *   (= (= t3 t4) (= t1 t2))                         (= (= t1 t2) false)
     141                 :            :    *  --------------------------------------------------------------------- TR
     142                 :            :    *           (= (= t3 t4) false)
     143                 :            :    *          --------------------- MACRO_SR_PRED_TRANSFORM
     144                 :            :    *           (= (= t4 t3) false)
     145                 :            :    *
     146                 :            :    * whereas the last step is only necessary if the conclusion has the arguments
     147                 :            :    * in reverse order than expected. Note that the original step represents two
     148                 :            :    * substitutions happening on the disequality, from t1->t3 and t2->t4, which
     149                 :            :    * are implicitly justified by transitivity steps that need to be made
     150                 :            :    * explicity. Since there is no sense of ordering among which premisis (other
     151                 :            :    * than (= (= t1 t2) false)) are used for which substitution, the transitivity
     152                 :            :    * proofs are built greedly by searching the sets of premises.
     153                 :            :    *
     154                 :            :    * If in either of the above cases then the conclusion is directly derived
     155                 :            :    * in the call, so only in the other cases we try to build a transitivity
     156                 :            :    * step below
     157                 :            :    *
     158                 :            :    * @param conclusion the conclusion of the (possibly) coarse-grained
     159                 :            :    * transitivity step
     160                 :            :    * @param premises the premises of the (possibly) coarse-grained
     161                 :            :    * transitivity step
     162                 :            :    * @param p a pointer to a CDProof to store the conversion of this EqProof
     163                 :            :    * @param assumptions the assumptions (and variants) of the original
     164                 :            :    * EqProof. These are necessary to avoid cyclic proofs, which could be
     165                 :            :    * generated by creating transitivity steps for assumptions (which depend on
     166                 :            :    * themselves).
     167                 :            :    * @return True if the EqProof transitivity step is in either of the above
     168                 :            :    * cases, symbolizing that the ProofNode justifying the conclusion has already
     169                 :            :    * been produced.
     170                 :            :    */
     171                 :            :   bool expandTransitivityForDisequalities(
     172                 :            :       Node conclusion,
     173                 :            :       std::vector<Node>& premises,
     174                 :            :       CDProof* p,
     175                 :            :       std::unordered_set<Node>& assumptions) const;
     176                 :            : 
     177                 :            :   /** Expand coarse-grained transitivity steps for theory disequalities
     178                 :            :    *
     179                 :            :    * Currently the equality engine can represent disequality reasoning of theory
     180                 :            :    * symbols in a rather coarse-grained manner with EqProof. This is the case
     181                 :            :    * when EqProof is
     182                 :            :    *            (= t1 c1) (= t2 c2)
     183                 :            :    *  ------------------------------------- EQP::TR
     184                 :            :    *             (= (t1 t2) false)
     185                 :            :    *
     186                 :            :    * which is converted into
     187                 :            :    *
     188                 :            :    *   (= t1 c1)        (= t2 c2)
     189                 :            :    *  -------------------------- CONG  --------------------- MACRO_SR_PRED_INTRO
     190                 :            :    *   (= (= t1 t2) (= c1 t2))           (= (= c1 c2) false)
     191                 :            :    *  --------------------------------------------------------- TR
     192                 :            :    *           (= (= t1 t2) false)
     193                 :            :    *
     194                 :            :    * @param conclusion the conclusion of the (possibly) coarse-grained
     195                 :            :    * transitivity step
     196                 :            :    * @param premises the premises of the (possibly) coarse-grained
     197                 :            :    * transitivity step
     198                 :            :    * @param p a pointer to a CDProof to store the conversion of this EqProof
     199                 :            :    * @return True if the EqProof transitivity step is the above case,
     200                 :            :    * indicating that the ProofNode justifying the conclusion has already been
     201                 :            :    * produced.
     202                 :            :    */
     203                 :            :   bool expandTransitivityForTheoryDisequalities(Node conclusion,
     204                 :            :                                                 std::vector<Node>& premises,
     205                 :            :                                                 CDProof* p) const;
     206                 :            : 
     207                 :            :   /** Builds a transitivity chain from equalities to derive a conclusion
     208                 :            :    *
     209                 :            :    * Given an equality (= t1 tn), and a list of equalities premises, attempts to
     210                 :            :    * build a chain (= t1 t2) ... (= tn-1 tn) from premises. This is done in a
     211                 :            :    * greedy manner by finding one "link" in the chain at a time, updating the
     212                 :            :    * conclusion to be the next link and the premises by removing the used
     213                 :            :    * premise, and searching recursively.
     214                 :            :    *
     215                 :            :    * Consider for example
     216                 :            :    * - conclusion: (= t1 t4)
     217                 :            :    * - premises:   (= t4 t2), (= t2 t3), (= t2 t1), (= t3 t4)
     218                 :            :    *
     219                 :            :    * It proceeds by searching for t1 in an equality in the premises, in order,
     220                 :            :    * which is found in the equality (= t2 t1). Since t2 != t4, it attempts to
     221                 :            :    * build a chain with
     222                 :            :    * - conclusion (= t2 t4)
     223                 :            :    * - premises (= t4 t2), (= t2 t3), (= t3 t4)
     224                 :            :    *
     225                 :            :    * In the first equality it finds t2 and also t4, which closes the chain, so
     226                 :            :    * that premises is updated to (= t2 t4) and the method returns true. Since
     227                 :            :    * the recursive call was successful, the original conclusion (= t1 t4) is
     228                 :            :    * justified with (= t1 t2) plus the chain built in the recursive call,
     229                 :            :    * i.e. (= t1 t2), (= t2 t4).
     230                 :            :    *
     231                 :            :    * Note that not all the premises were necessary to build a successful
     232                 :            :    * chain. Moreover, note that building a successful chain can depend on the
     233                 :            :    * order in which the equalities are chosen. When a recursive call fails to
     234                 :            :    * close a chain, the chosen equality is dismissed and another is searched for
     235                 :            :    * among the remaining ones.
     236                 :            :    *
     237                 :            :    * This method assumes that premises does not contain reflexivity premises.
     238                 :            :    * This is without loss of generality since such premises are spurious for a
     239                 :            :    * transitivity step.
     240                 :            :    *
     241                 :            :    * @param conclusion the conclusion of the transitivity chain of equalities
     242                 :            :    * @param premises the list of equalities to build a chain with
     243                 :            :    * @return whether premises successfully build a transitivity chain for the
     244                 :            :    * conclusion
     245                 :            :    */
     246                 :            :   bool buildTransitivityChain(Node conclusion,
     247                 :            :                               std::vector<Node>& premises) const;
     248                 :            : 
     249                 :            :   /** Reduce a congruence EqProof into a transitivity matrix
     250                 :            :    *
     251                 :            :    * Given a congruence EqProof of (= (f a0 ... an-1) (f b0 ... bn-1)), reduce
     252                 :            :    * its justification into a matrix
     253                 :            :    *
     254                 :            :    *   [0]   -> p_{0,0} ... p_{m_0,0}
     255                 :            :    *   ...
     256                 :            :    *   [n-1] -> p_{0,n} ... p_{m_n-1,n-1}
     257                 :            :    *
     258                 :            :    * where f has arity n and each p_{0,i} ... p_{m_i, i} is a transitivity chain
     259                 :            :    * (modulo ordering) justifying (= ai bi).
     260                 :            :    *
     261                 :            :    * Congruence steps in EqProof are binary, representing reasoning over curried
     262                 :            :    * applications. In the simplest case the general shape of a congruence
     263                 :            :    * EqProof is:
     264                 :            :    *                                     P0
     265                 :            :    *              ------- EQP::REFL  ----------
     266                 :            :    *       P1        []               (= a0 b0)
     267                 :            :    *  ---------   ----------------------- EQP::CONG
     268                 :            :    *  (= a1 b1)             []                        P2
     269                 :            :    *  ------------------------- EQP::CONG        -----------
     270                 :            :    *             []                               (= a2 b2)
     271                 :            :    *          ------------------------------------------------ EQP::CONG
     272                 :            :    *                  (= (f a0 a1 a2) (f b0 b1 b2))
     273                 :            :    *
     274                 :            :    * where [] stands for the null node, symbolizing "equality between partial
     275                 :            :    * applications".
     276                 :            :    *
     277                 :            :    * The reduction of such a proof is done by
     278                 :            :    * - converting the proof of the second CONG premise (via addToProof) and
     279                 :            :    *   adding the resulting node to row i of the matrix
     280                 :            :    * - recursively reducing the first proof with i-1
     281                 :            :    *
     282                 :            :    * In the above case the transitivity matrix would thus be
     283                 :            :    *   [0] -> (= a0 b0)
     284                 :            :    *   [1] -> (= a1 b1)
     285                 :            :    *   [2] -> (= a2 b2)
     286                 :            :    *
     287                 :            :    * The more complex case of congruence proofs has transitivity steps as the
     288                 :            :    * first child of CONG steps. For example
     289                 :            :    *                                     P0
     290                 :            :    *              ------- EQP::REFL  ----------
     291                 :            :    *     P'          []            (= a0 c)
     292                 :            :    *  ---------   ----------------------------- EQP::CONG
     293                 :            :    *  (= b0 c)             []                               P1
     294                 :            :    * ------------------------- EQP::TRANS             -----------
     295                 :            :    *            []                                     (= a1 b1)
     296                 :            :    *         ----------------------------------------------------- EQP::CONG
     297                 :            :    *                          (= (f a0 a1) (f b0 b1))
     298                 :            :    *
     299                 :            :    * where when the first child of CONG is a transitivity step
     300                 :            :    * - the premises that are CONG steps are recursively reduced with *the same*
     301                 :            :    *   argument i
     302                 :            :    * - the other premises are processed with addToProof and added to the i row
     303                 :            :    *   in the matrix
     304                 :            :    *
     305                 :            :    * In the above example the corresponding transitivity matrix is
     306                 :            :    *   [0] -> (= a0 c), (= b0 c)
     307                 :            :    *   [1] -> (= a1 b1)
     308                 :            :    *
     309                 :            :    * The remaining complication is when the conclusion is an equality of n-ary
     310                 :            :    * applications of *different* arities. Then there necessarily is a
     311                 :            :    * transitivity step as a first child a CONG step whose conclusion is an
     312                 :            :    * equality of n-ary applications of different arities. For example
     313                 :            :    *
     314                 :            :    *             P0                              P1
     315                 :            :    * -------------------------- EQP::TRANS  -----------
     316                 :            :    *     (= (f a0 a1) (f b0))                (= a2 b1)
     317                 :            :    * -------------------------------------------------- EQP::CONG
     318                 :            :    *              (= (f a0 a1 a2) (f b0 b1))
     319                 :            :    *
     320                 :            :    * will be first reduced with i = 2 (maximal arity among the original
     321                 :            :    * conclusion's applications), adding (= a2 b1) to row 2 after processing
     322                 :            :    * P1. The first child is reduced with i = 1. Since it is a TRANS step whose
     323                 :            :    * conclusion is an equality of n-ary applications with mismatching arity, P0
     324                 :            :    * is processed with addToProof and the result is added to row 1. Thus the
     325                 :            :    * transitivity matrix is
     326                 :            :    *   [0] ->
     327                 :            :    *   [1] -> (= (f a0 a1) (f b0))
     328                 :            :    *   [2] -> (= a2 b1)
     329                 :            :    *
     330                 :            :    * The empty row 0 is used by the original caller of reduceNestedCongruence to
     331                 :            :    * compute that the above congruence proof's conclusion is
     332                 :            :    *   (= (f (f a0 a1) a2) (f (f b0) b1))
     333                 :            :    *
     334                 :            :    * @param i the i-th argument of the congruent applications, initially being
     335                 :            :    * the maximal arity among conclusion's applications.
     336                 :            :    * @param conclusion the original congruence conclusion
     337                 :            :    * @param transitivityMatrix a matrix of equalities with each row justifying
     338                 :            :    * an equality between the congruent applications
     339                 :            :    * @param p a pointer to a CDProof to store the conversion of this EqProof
     340                 :            :    * @param visited a cache of the original EqProof conclusions and the
     341                 :            :    * resulting conclusion after conversion.
     342                 :            :    * @param assumptions the assumptions (and variants) of the original EqProof
     343                 :            :    * @param isNary whether conclusion is an equality of n-ary applications
     344                 :            :    */
     345                 :            :   void reduceNestedCongruence(
     346                 :            :       unsigned i,
     347                 :            :       Node conclusion,
     348                 :            :       std::vector<std::vector<Node>>& transitivityMatrix,
     349                 :            :       CDProof* p,
     350                 :            :       std::unordered_map<Node, Node>& visited,
     351                 :            :       std::unordered_set<Node>& assumptions,
     352                 :            :       bool isNary) const;
     353                 :            : 
     354                 :            : }; /* class EqProof */
     355                 :            : 
     356                 :            : }  // Namespace eq
     357                 :            : }  // Namespace theory
     358                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14