LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/proof/dot - dot_printer.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 242 0.0 %
Date: 2025-01-30 13:40:10 Functions: 0 18 0.0 %
Branches: 0 144 0.0 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * Top contributors (to current version):
       3                 :            :  *   Vinícius Braga Freire, Haniel Barbosa, Diego Della Rocca de Camargos
       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                 :            :  * Implemantation of the module for printing dot proofs.
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "proof/dot/dot_printer.h"
      17                 :            : 
      18                 :            : #include <algorithm>
      19                 :            : #include <sstream>
      20                 :            : 
      21                 :            : #include "options/expr_options.h"
      22                 :            : #include "options/printer_options.h"
      23                 :            : #include "options/proof_options.h"
      24                 :            : #include "printer/smt2/smt2_printer.h"
      25                 :            : #include "proof/proof_checker.h"
      26                 :            : #include "proof/proof_node_algorithm.h"
      27                 :            : #include "proof/proof_node_manager.h"
      28                 :            : #include "proof/trust_id.h"
      29                 :            : #include "theory/builtin/proof_checker.h"
      30                 :            : 
      31                 :            : namespace cvc5::internal {
      32                 :            : namespace proof {
      33                 :            : 
      34                 :          0 : DotPrinter::DotPrinter(Env& env)
      35                 :            :     : EnvObj(env),
      36                 :            :       d_lbind(
      37                 :            :           "let",
      38                 :          0 :           options().printer.dagThresh ? options().printer.dagThresh + 1 : 0),
      39         [ -  - ]:          0 :       d_ruleID(0)
      40                 :            : {
      41                 :          0 :   const std::string acronyms[5] = {"SAT", "CNF", "TL", "PP", "IN"};
      42                 :          0 :   const std::string colors[5] = {"purple", "yellow", "green", "brown", "blue"};
      43                 :            : 
      44         [ -  - ]:          0 :   for (unsigned i = 0; i < 5; i++)
      45                 :            :   {
      46                 :          0 :     d_subgraphsStr.push_back(std::ostringstream());
      47                 :          0 :     d_subgraphsStr[i] << "\n\tsubgraph cluster_" << acronyms[i]
      48                 :          0 :                       << " {\n\t\tlabel=\"" << acronyms[i]
      49                 :          0 :                       << "\"\n\t\tbgcolor=\"" << colors[i] << "\"\n\t\t";
      50                 :            :   }
      51                 :          0 : }
      52                 :            : 
      53                 :          0 : DotPrinter::~DotPrinter() {}
      54                 :            : 
      55                 :          0 : std::string DotPrinter::sanitizeStringDoubleQuotes(const std::string& s)
      56                 :            : {
      57                 :          0 :   std::string newS;
      58                 :          0 :   newS.reserve(s.size());
      59         [ -  - ]:          0 :   for (const char c : s)
      60                 :            :   {
      61 [ -  - ][ -  - ]:          0 :     switch (c)
            [ -  - ][ - ]
      62                 :            :     {
      63                 :          0 :       case '\"': newS += "\\\\\\\""; break;
      64                 :          0 :       case '>': newS += "\\>"; break;
      65                 :          0 :       case '<': newS += "\\<"; break;
      66                 :          0 :       case '{': newS += "\\{"; break;
      67                 :          0 :       case '}': newS += "\\}"; break;
      68                 :          0 :       case '|': newS += "\\|"; break;
      69                 :          0 :       default: newS += c; break;
      70                 :            :     }
      71                 :            :   }
      72                 :            : 
      73                 :          0 :   return newS;
      74                 :            : }
      75                 :            : 
      76                 :          0 : std::string DotPrinter::sanitizeString(const std::string& s)
      77                 :            : {
      78                 :          0 :   std::string newS;
      79                 :          0 :   newS.reserve(s.size());
      80         [ -  - ]:          0 :   for (const char c : s)
      81                 :            :   {
      82 [ -  - ][ -  - ]:          0 :     switch (c)
            [ -  - ][ - ]
      83                 :            :     {
      84                 :          0 :       case '\"': newS += "\\\""; break;
      85                 :          0 :       case '>': newS += "\\>"; break;
      86                 :          0 :       case '<': newS += "\\<"; break;
      87                 :          0 :       case '{': newS += "\\{"; break;
      88                 :          0 :       case '}': newS += "\\}"; break;
      89                 :          0 :       case '|': newS += "\\|"; break;
      90                 :          0 :       default: newS += c; break;
      91                 :            :     }
      92                 :            :   }
      93                 :            : 
      94                 :          0 :   return newS;
      95                 :            : }
      96                 :            : 
      97                 :          0 : void DotPrinter::countSubproofs(const ProofNode* pn)
      98                 :            : {
      99                 :          0 :   std::vector<const ProofNode*> visit;
     100                 :          0 :   std::unordered_map<const ProofNode*, bool> visited;
     101                 :          0 :   std::unordered_map<const ProofNode*, bool>::iterator it;
     102                 :            :   const ProofNode* cur;
     103                 :          0 :   visit.push_back(pn);
     104                 :          0 :   do
     105                 :            :   {
     106                 :          0 :     cur = visit.back();
     107                 :          0 :     visit.pop_back();
     108                 :          0 :     it = visited.find(cur);
     109         [ -  - ]:          0 :     if (it == visited.end())
     110                 :            :     {
     111                 :          0 :       visited[cur] = false;
     112                 :          0 :       visit.push_back(cur);
     113                 :            :       const std::vector<std::shared_ptr<ProofNode>>& children =
     114                 :          0 :           cur->getChildren();
     115         [ -  - ]:          0 :       for (const std::shared_ptr<ProofNode>& c : children)
     116                 :            :       {
     117                 :          0 :         visit.push_back(c.get());
     118                 :            :       }
     119                 :            :     }
     120         [ -  - ]:          0 :     else if (!it->second)
     121                 :            :     {
     122                 :          0 :       visited[cur] = true;
     123                 :          0 :       size_t counter = 1;
     124                 :            :       const std::vector<std::shared_ptr<ProofNode>>& children =
     125                 :          0 :           cur->getChildren();
     126         [ -  - ]:          0 :       for (const std::shared_ptr<ProofNode>& c : children)
     127                 :            :       {
     128                 :          0 :         counter += d_subpfCounter[c.get()];
     129                 :            :       }
     130                 :          0 :       d_subpfCounter[cur] = counter;
     131                 :            :     }
     132         [ -  - ]:          0 :   } while (!visit.empty());
     133                 :          0 : }
     134                 :            : 
     135                 :          0 : void DotPrinter::letifyResults(const ProofNode* pn)
     136                 :            : {
     137                 :          0 :   std::vector<const ProofNode*> visit;
     138                 :          0 :   std::unordered_set<const ProofNode*> visited;
     139                 :          0 :   std::unordered_set<const ProofNode*>::iterator it;
     140                 :            :   const ProofNode* cur;
     141                 :          0 :   visit.push_back(pn);
     142                 :          0 :   do
     143                 :            :   {
     144                 :          0 :     cur = visit.back();
     145                 :          0 :     visit.pop_back();
     146                 :          0 :     it = visited.find(cur);
     147         [ -  - ]:          0 :     if (it == visited.end())
     148                 :            :     {
     149                 :          0 :       d_lbind.process(cur->getResult());
     150                 :          0 :       visited.insert(cur);
     151                 :            :       const std::vector<std::shared_ptr<ProofNode>>& children =
     152                 :          0 :           cur->getChildren();
     153         [ -  - ]:          0 :       for (const std::shared_ptr<ProofNode>& c : children)
     154                 :            :       {
     155                 :          0 :         visit.push_back(c.get());
     156                 :            :       }
     157                 :            :     }
     158         [ -  - ]:          0 :   } while (!visit.empty());
     159                 :          0 : }
     160                 :            : 
     161                 :          0 : void DotPrinter::print(std::ostream& out, const ProofNode* pn)
     162                 :            : {
     163                 :          0 :   countSubproofs(pn);
     164                 :          0 :   letifyResults(pn);
     165                 :            : 
     166                 :            :   // The dot attribute rankdir="BT" sets the direction of the graph layout,
     167                 :            :   // placing the root node at the top. The "node [shape..." attribute sets the
     168                 :            :   // shape of all nodes to record.
     169                 :          0 :   out << "digraph proof {\n\trankdir=\"BT\";\n\tnode [shape=record];\n";
     170                 :            :   // print let map
     171                 :          0 :   std::vector<Node> letList;
     172                 :          0 :   d_lbind.letify(letList);
     173         [ -  - ]:          0 :   if (!letList.empty())
     174                 :            :   {
     175                 :          0 :     out << "\tcomment=\"{\\\"letMap\\\" : {";
     176                 :          0 :     bool first = true;
     177         [ -  - ]:          0 :     for (TNode n : letList)
     178                 :            :     {
     179                 :          0 :       size_t id = d_lbind.getId(n);
     180                 :          0 :       Assert(id != 0);
     181         [ -  - ]:          0 :       if (!first)
     182                 :            :       {
     183                 :          0 :         out << ", ";
     184                 :            :       }
     185                 :            :       else
     186                 :            :       {
     187                 :          0 :         first = false;
     188                 :            :       }
     189                 :          0 :       out << "\\\"let" << id << "\\\" : \\\"";
     190                 :          0 :       std::ostringstream nStr;
     191                 :          0 :       nStr << d_lbind.convert(n, false);
     192                 :          0 :       std::string astring = nStr.str();
     193                 :            :       // we double the scaping of quotes because "simple scape" is ambiguous
     194                 :            :       // with the scape of the delimiter of the value in the key-value map
     195                 :          0 :       out << sanitizeStringDoubleQuotes(astring) << "\\\"";
     196                 :            :     }
     197                 :          0 :     out << "}}\";\n";
     198                 :            :   }
     199                 :            : 
     200                 :          0 :   std::map<size_t, uint64_t> proofLet;
     201                 :          0 :   std::map<size_t, uint64_t> firstScopeLet;
     202                 :          0 :   std::unordered_map<const ProofNode*, bool> cfaMap;
     203                 :          0 :   std::vector<size_t> ancestorHashs;
     204                 :            : 
     205                 :          0 :   DotPrinter::printInternal(out,
     206                 :            :                             pn,
     207                 :            :                             proofLet,
     208                 :            :                             firstScopeLet,
     209                 :            :                             cfaMap,
     210                 :            :                             ancestorHashs,
     211                 :            :                             ProofNodeClusterType::NOT_DEFINED);
     212                 :            : 
     213         [ -  - ]:          0 :   if (options().proof.printDotClusters)
     214                 :            :   {
     215                 :            :     // Print the sub-graphs
     216         [ -  - ]:          0 :     for (unsigned i = 0; i < 5; i++)
     217                 :            :     {
     218                 :          0 :       out << d_subgraphsStr[i].str() << "\n\t};";
     219                 :            :     }
     220                 :            :   }
     221                 :          0 :   out << "\n}\n";
     222                 :          0 : }
     223                 :            : 
     224                 :          0 : uint64_t DotPrinter::printInternal(
     225                 :            :     std::ostream& out,
     226                 :            :     const ProofNode* pn,
     227                 :            :     std::map<size_t, uint64_t>& pfLetClosed,
     228                 :            :     std::map<size_t, uint64_t>& pfLetOpen,
     229                 :            :     std::unordered_map<const ProofNode*, bool>& cfaMap,
     230                 :            :     std::vector<size_t>& ancestorHashs,
     231                 :            :     ProofNodeClusterType parentType)
     232                 :            : {
     233                 :          0 :   uint64_t currentRuleID = d_ruleID;
     234                 :            : 
     235                 :            :   // Print DAG option enabled
     236         [ -  - ]:          0 :   if (options().proof.printDotAsDAG)
     237                 :            :   {
     238                 :            :     ProofNodeHashFunction hasher;
     239                 :          0 :     size_t currentHash = hasher(pn);
     240                 :            : 
     241                 :          0 :     std::vector<size_t>::iterator oldEnd = ancestorHashs.end();
     242                 :            :     // Search if the current hash is in the vector
     243                 :            :     std::vector<size_t>::iterator it =
     244                 :          0 :         std::find(ancestorHashs.begin(), ancestorHashs.end(), currentHash);
     245                 :            : 
     246                 :            :     // Register the current proof node hash in the ancestor vector
     247                 :          0 :     ancestorHashs.push_back(currentHash);
     248                 :            : 
     249                 :            :     // we only consider sharing when this would not introduce a cycle, which
     250                 :            :     // would be the case if this hash is occurring under a proof node with the
     251                 :            :     // same hash (this can happen since our hash computation only takes into
     252                 :            :     // account the immediate descendants of a proof node, the limit of hash
     253                 :            :     // representation notwithstanding)
     254         [ -  - ]:          0 :     if (it == oldEnd)
     255                 :            :     {
     256                 :          0 :       auto openProofIt = pfLetOpen.find(currentHash);
     257                 :            : 
     258         [ -  - ]:          0 :       if (openProofIt != pfLetOpen.end())
     259                 :            :       {
     260                 :          0 :         return openProofIt->second;
     261                 :            :       }
     262                 :            : 
     263                 :          0 :       auto proofIt = pfLetClosed.find(currentHash);
     264                 :            :       // If this node has been already saved to the global cache of closed proof
     265                 :            :       // nodes
     266         [ -  - ]:          0 :       if (proofIt != pfLetClosed.end())
     267                 :            :       {
     268                 :          0 :         Assert(!expr::containsAssumption(pn, cfaMap));
     269                 :          0 :         return proofIt->second;
     270                 :            :       }
     271                 :            :       // If this proof node is closed, we add it to the global cache
     272         [ -  - ]:          0 :       if (!expr::containsAssumption(pn, cfaMap))
     273                 :            :       {
     274                 :          0 :         pfLetClosed[currentHash] = currentRuleID;
     275                 :            :       }
     276                 :          0 :       pfLetOpen[currentHash] = currentRuleID;
     277                 :            :     }
     278                 :            :   }
     279                 :            : 
     280                 :          0 :   ProofNodeClusterType proofNodeType = ProofNodeClusterType::NOT_DEFINED;
     281         [ -  - ]:          0 :   if (options().proof.printDotClusters)
     282                 :            :   {
     283                 :            :     // Define the type of this node
     284                 :          0 :     proofNodeType = defineProofNodeType(pn, parentType);
     285         [ -  - ]:          0 :     if (proofNodeType != ProofNodeClusterType::FIRST_SCOPE
     286         [ -  - ]:          0 :         && proofNodeType != ProofNodeClusterType::NOT_DEFINED)
     287                 :            :     {
     288                 :          0 :       d_subgraphsStr[static_cast<int>(proofNodeType) - 1] << d_ruleID << " ";
     289                 :            :     }
     290                 :            :   }
     291                 :            : 
     292                 :          0 :   printProofNodeInfo(out, pn);
     293                 :            : 
     294                 :          0 :   d_ruleID++;
     295                 :            : 
     296                 :          0 :   ProofRule r = pn->getRule();
     297                 :            : 
     298                 :            :   // Scopes trigger a traversal with a new local cache for proof nodes
     299 [ -  - ][ -  - ]:          0 :   if (isSCOPE(r) && currentRuleID)
                 [ -  - ]
     300                 :            :   {
     301                 :            :     // create a new pfLet
     302                 :          0 :     std::map<size_t, uint64_t> thisScopeLet;
     303                 :          0 :     uint64_t childId = printInternal(out,
     304                 :          0 :                                      pn->getChildren()[0].get(),
     305                 :            :                                      pfLetClosed,
     306                 :            :                                      thisScopeLet,
     307                 :            :                                      cfaMap,
     308                 :            :                                      ancestorHashs,
     309                 :            :                                      proofNodeType);
     310                 :          0 :     out << "\t" << childId << " -> " << currentRuleID << ";\n";
     311         [ -  - ]:          0 :     if (options().proof.printDotAsDAG)
     312                 :            :     {
     313                 :          0 :       ancestorHashs.pop_back();
     314                 :            :     }
     315                 :            :   }
     316                 :            :   else
     317                 :            :   {
     318                 :          0 :     const std::vector<std::shared_ptr<ProofNode>>& children = pn->getChildren();
     319         [ -  - ]:          0 :     for (const std::shared_ptr<ProofNode>& c : children)
     320                 :            :     {
     321                 :          0 :       uint64_t childId = printInternal(out,
     322                 :          0 :                                        c.get(),
     323                 :            :                                        pfLetClosed,
     324                 :            :                                        pfLetOpen,
     325                 :            :                                        cfaMap,
     326                 :            :                                        ancestorHashs,
     327                 :            :                                        proofNodeType);
     328                 :          0 :       out << "\t" << childId << " -> " << currentRuleID << ";\n";
     329         [ -  - ]:          0 :       if (options().proof.printDotAsDAG)
     330                 :            :       {
     331                 :          0 :         ancestorHashs.pop_back();
     332                 :            :       }
     333                 :            :     }
     334                 :            :   }
     335                 :            : 
     336                 :            :   // If it's a scope, then remove from the stack
     337                 :          0 :   if (isSCOPE(r) && options().proof.printDotClusters)
     338                 :            :   {
     339                 :          0 :     d_scopesArgs.pop_back();
     340                 :            :   }
     341                 :            : 
     342                 :          0 :   return currentRuleID;
     343                 :            : }
     344                 :            : 
     345                 :          0 : void DotPrinter::printProofNodeInfo(std::ostream& out, const ProofNode* pn)
     346                 :            : {
     347                 :          0 :   std::ostringstream currentArguments, resultStr, classes, colors;
     348                 :            : 
     349                 :          0 :   out << "\t" << d_ruleID << " [ label = \"{";
     350                 :            : 
     351                 :          0 :   resultStr << d_lbind.convert(pn->getResult());
     352                 :          0 :   std::string astring = resultStr.str();
     353                 :          0 :   out << sanitizeString(astring);
     354                 :            : 
     355                 :          0 :   ProofRule r = pn->getRule();
     356                 :          0 :   DotPrinter::ruleArguments(currentArguments, pn);
     357                 :          0 :   astring = currentArguments.str();
     358                 :          0 :   out << "|" << r << sanitizeString(astring) << "}\"";
     359                 :            : 
     360                 :            :   // add number of subchildren
     361                 :            :   std::map<const ProofNode*, size_t>::const_iterator it =
     362                 :          0 :       d_subpfCounter.find(pn);
     363                 :          0 :   out << ", comment = \"{\\\"subProofQty\\\":" << it->second << "}\" ];\n";
     364                 :          0 : }
     365                 :            : 
     366                 :          0 : ProofNodeClusterType DotPrinter::defineProofNodeType(const ProofNode* pn,
     367                 :            :                                                      ProofNodeClusterType last)
     368                 :            : {
     369                 :          0 :   ProofRule rule = pn->getRule();
     370         [ -  - ]:          0 :   if (isSCOPE(rule))
     371                 :            :   {
     372                 :          0 :     d_scopesArgs.push_back(pn->getArguments());
     373                 :            :   }
     374                 :            : 
     375                 :            :   // If is the first node
     376         [ -  - ]:          0 :   if (!d_ruleID)
     377                 :            :   {
     378                 :          0 :     return ProofNodeClusterType::FIRST_SCOPE;
     379                 :            :   }
     380                 :            :   // If the rule is in the SAT range and the last node was: FF or SAT
     381 [ -  - ][ -  - ]:          0 :   if (last <= ProofNodeClusterType::SAT && isSat(rule))
                 [ -  - ]
     382                 :            :   {
     383                 :          0 :     return ProofNodeClusterType::SAT;
     384                 :            :   }
     385                 :            :   // If is a ASSUME
     386         [ -  - ]:          0 :   if (isASSUME(rule))
     387                 :            :   {
     388         [ -  - ]:          0 :     if (isInput(pn))
     389                 :            :     {
     390                 :          0 :       return ProofNodeClusterType::INPUT;
     391                 :            :     }
     392                 :          0 :     return last;
     393                 :            :   }
     394                 :            :   // the last node was: FS, SAT or CNF
     395         [ -  - ]:          0 :   if (last <= ProofNodeClusterType::CNF)
     396                 :            :   {
     397                 :            :     // If the rule is in the CNF range
     398         [ -  - ]:          0 :     if (isCNF(rule))
     399                 :            :     {
     400                 :          0 :       return ProofNodeClusterType::CNF;
     401                 :            :     }
     402                 :            :     // If the first rule after a CNF is in the TL range
     403         [ -  - ]:          0 :     if (isTheoryLemma(pn))
     404                 :            :     {
     405                 :          0 :       return ProofNodeClusterType::THEORY_LEMMA;
     406                 :            :     }
     407                 :            :     // Is not a scope
     408                 :          0 :     return ProofNodeClusterType::PRE_PROCESSING;
     409                 :            :   }
     410                 :            :   // If the last rule was pre processing
     411         [ -  - ]:          0 :   if (last == ProofNodeClusterType::PRE_PROCESSING)
     412                 :            :   {
     413                 :          0 :     return ProofNodeClusterType::PRE_PROCESSING;
     414                 :            :   }
     415                 :            :   // If the last rule was theory lemma
     416         [ -  - ]:          0 :   if (last == ProofNodeClusterType::THEORY_LEMMA)
     417                 :            :   {
     418                 :          0 :     return ProofNodeClusterType::THEORY_LEMMA;
     419                 :            :   }
     420                 :            : 
     421                 :          0 :   return ProofNodeClusterType::NOT_DEFINED;
     422                 :            : }
     423                 :            : 
     424                 :          0 : inline bool DotPrinter::isInput(const ProofNode* pn)
     425                 :            : {
     426                 :          0 :   const TNode& thisAssumeArg = pn->getArguments()[0];
     427                 :          0 :   auto& firstScope = d_scopesArgs[0].get();
     428                 :            : 
     429                 :            :   // Verifies if the arg of this assume are in the first scope
     430                 :          0 :   if (std::find(firstScope.begin(), firstScope.end(), thisAssumeArg)
     431         [ -  - ]:          0 :       == firstScope.end())
     432                 :            :   {
     433                 :          0 :     return false;
     434                 :            :   }
     435                 :            : 
     436                 :            :   // Verifies if the arg of this assume is at any of the other scopes
     437         [ -  - ]:          0 :   for (size_t i = d_scopesArgs.size() - 1; i > 0; i--)
     438                 :            :   {
     439                 :          0 :     auto& args = d_scopesArgs[i].get();
     440                 :            : 
     441         [ -  - ]:          0 :     if (std::find(args.begin(), args.end(), thisAssumeArg) != args.end())
     442                 :            :     {
     443                 :          0 :       return false;
     444                 :            :     }
     445                 :            :   }
     446                 :            : 
     447                 :          0 :   return true;
     448                 :            : }
     449                 :            : 
     450                 :          0 : inline bool DotPrinter::isSat(const ProofRule& rule)
     451                 :            : {
     452                 :          0 :   return ProofRule::CHAIN_RESOLUTION <= rule
     453 [ -  - ][ -  - ]:          0 :          && rule <= ProofRule::MACRO_RESOLUTION_TRUST;
     454                 :            : }
     455                 :            : 
     456                 :          0 : inline bool DotPrinter::isCNF(const ProofRule& rule)
     457                 :            : {
     458 [ -  - ][ -  - ]:          0 :   return ProofRule::NOT_NOT_ELIM <= rule && rule <= ProofRule::CNF_ITE_NEG3;
     459                 :            : }
     460                 :            : 
     461                 :          0 : inline bool DotPrinter::isSCOPE(const ProofRule& rule)
     462                 :            : {
     463                 :          0 :   return ProofRule::SCOPE == rule;
     464                 :            : }
     465                 :            : 
     466                 :          0 : inline bool DotPrinter::isTheoryLemma(const ProofNode* pn)
     467                 :            : {
     468                 :          0 :   ProofRule rule = pn->getRule();
     469         [ -  - ]:          0 :   if (rule == ProofRule::TRUST)
     470                 :            :   {
     471                 :            :     TrustId tid;
     472         [ -  - ]:          0 :     if (getTrustId(pn->getArguments()[0], tid))
     473                 :            :     {
     474                 :          0 :       return tid == TrustId::THEORY_LEMMA;
     475                 :            :     }
     476                 :            :   }
     477                 :            :   return rule == ProofRule::SCOPE
     478 [ -  - ][ -  - ]:          0 :          || (ProofRule::CNF_ITE_NEG3 < rule && rule < ProofRule::LFSC_RULE);
                 [ -  - ]
     479                 :            : }
     480                 :            : 
     481                 :          0 : inline bool DotPrinter::isASSUME(const ProofRule& rule)
     482                 :            : {
     483                 :          0 :   return ProofRule::ASSUME == rule;
     484                 :            : }
     485                 :            : 
     486                 :          0 : void DotPrinter::ruleArguments(std::ostringstream& currentArguments,
     487                 :            :                                const ProofNode* pn)
     488                 :            : {
     489                 :          0 :   const std::vector<Node>& args = pn->getArguments();
     490                 :          0 :   ProofRule r = pn->getRule();
     491                 :            :   // don't process arguments of rules whose conclusion is in the arguments
     492 [ -  - ][ -  - ]:          0 :   if (!args.size() || r == ProofRule::ASSUME || r == ProofRule::REORDERING
     493 [ -  - ][ -  - ]:          0 :       || r == ProofRule::REFL)
                 [ -  - ]
     494                 :            :   {
     495                 :          0 :     return;
     496                 :            :   }
     497                 :          0 :   currentArguments << " :args [ ";
     498                 :            : 
     499                 :            :   // if cong, special process
     500 [ -  - ][ -  - ]:          0 :   if (r == ProofRule::CONG || r == ProofRule::NARY_CONG)
     501                 :            :   {
     502                 :          0 :     AlwaysAssert(args.size() == 1 || args.size() == 2);
     503                 :            :     // if two arguments, ignore first and print second
     504         [ -  - ]:          0 :     if (args.size() == 2)
     505                 :            :     {
     506                 :          0 :       currentArguments << d_lbind.convert(args[1]);
     507                 :            :     }
     508                 :            :     else
     509                 :            :     {
     510                 :          0 :       Kind k = Kind::UNDEFINED_KIND;
     511                 :          0 :       ProofRuleChecker::getKind(args[0], k);
     512                 :          0 :       currentArguments << printer::smt2::Smt2Printer::smtKindString(k);
     513                 :          0 :     }
     514                 :            :   }
     515                 :            :   // if th_rw, likewise
     516         [ -  - ]:          0 :   else if (r == ProofRule::TRUST_THEORY_REWRITE)
     517                 :            :   {
     518                 :            :     // print the second argument
     519                 :            :     theory::TheoryId id;
     520                 :          0 :     theory::builtin::BuiltinProofRuleChecker::getTheoryId(args[1], id);
     521                 :          0 :     std::ostringstream ss;
     522                 :          0 :     ss << id;
     523                 :          0 :     std::string s = ss.str();
     524                 :            :     // delete "THEORY_" prefix
     525                 :          0 :     s.erase(0, 7);
     526                 :          0 :     currentArguments << s;
     527                 :            :   }
     528                 :            :   else
     529                 :            :   {
     530                 :          0 :     currentArguments << d_lbind.convert(args[0]);
     531         [ -  - ]:          0 :     for (size_t i = 1, size = args.size(); i < size; i++)
     532                 :            :     {
     533                 :          0 :       currentArguments << ", " << d_lbind.convert(args[i]);
     534                 :            :     }
     535                 :            :   }
     536                 :          0 :   currentArguments << " ]";
     537                 :            : }
     538                 :            : 
     539                 :            : }  // namespace proof
     540                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14