LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/quantifiers/sygus - template_infer.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 93 96 96.9 %
Date: 2024-12-30 14:24:00 Functions: 4 4 100.0 %
Branches: 57 104 54.8 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * Top contributors (to current version):
       3                 :            :  *   Andrew Reynolds, Mathias Preiner, Aina Niemetz
       4                 :            :  *
       5                 :            :  * This file is part of the cvc5 project.
       6                 :            :  *
       7                 :            :  * Copyright (c) 2009-2024 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                 :            :  * Utility for processing single invocation synthesis conjectures.
      14                 :            :  */
      15                 :            : #include "theory/quantifiers/sygus/template_infer.h"
      16                 :            : 
      17                 :            : #include "expr/skolem_manager.h"
      18                 :            : #include "options/quantifiers_options.h"
      19                 :            : #include "theory/quantifiers/sygus/embedding_converter.h"
      20                 :            : #include "theory/quantifiers/sygus/sygus_utils.h"
      21                 :            : #include "theory/quantifiers/term_util.h"
      22                 :            : 
      23                 :            : using namespace cvc5::internal::kind;
      24                 :            : 
      25                 :            : namespace cvc5::internal {
      26                 :            : namespace theory {
      27                 :            : namespace quantifiers {
      28                 :            : 
      29                 :       7260 : SygusTemplateInfer::SygusTemplateInfer(Env& env) : EnvObj(env), d_ti(env) {}
      30                 :            : 
      31                 :       1163 : void SygusTemplateInfer::initialize(Node q)
      32                 :            : {
      33 [ -  + ][ -  + ]:       1163 :   Assert(d_quant.isNull());
                 [ -  - ]
      34 [ -  + ][ -  + ]:       1163 :   Assert(q.getKind() == Kind::FORALL);
                 [ -  - ]
      35                 :       1163 :   d_quant = q;
      36                 :            :   // We are processing without single invocation techniques, now check if
      37                 :            :   // we should fix an invariant template (post-condition strengthening or
      38                 :            :   // pre-condition weakening).
      39                 :       1163 :   options::SygusInvTemplMode tmode = options().quantifiers.sygusInvTemplMode;
      40         [ +  + ]:       1163 :   if (tmode != options::SygusInvTemplMode::NONE)
      41                 :            :   {
      42                 :            :     // currently only works for single predicate synthesis
      43                 :        674 :     if (q[0].getNumChildren() > 1 || !q[0][0].getType().isPredicate())
      44                 :            :     {
      45                 :        378 :       tmode = options::SygusInvTemplMode::NONE;
      46                 :            :     }
      47         [ +  - ]:        296 :     else if (!options().quantifiers.sygusInvTemplWhenSyntax)
      48                 :            :     {
      49                 :            :       // only use invariant templates if no syntactic restrictions
      50         [ +  + ]:        296 :       if (EmbeddingConverter::hasSyntaxRestrictions(q))
      51                 :            :       {
      52                 :        150 :         tmode = options::SygusInvTemplMode::NONE;
      53                 :            :       }
      54                 :            :     }
      55                 :            :   }
      56                 :            : 
      57         [ +  + ]:       1163 :   if (tmode == options::SygusInvTemplMode::NONE)
      58                 :            :   {
      59                 :            :     // not processing invariant templates
      60                 :       1119 :     return;
      61                 :            :   }
      62                 :            : 
      63                 :        146 :   Node qq;
      64                 :        146 :   if (q[1].getKind() == Kind::NOT && q[1][0].getKind() == Kind::FORALL)
      65                 :            :   {
      66                 :        139 :     qq = q[1][0][1];
      67                 :            :   }
      68                 :            :   else
      69                 :            :   {
      70                 :          7 :     qq = TermUtil::simpleNegate(q[1]);
      71                 :            :   }
      72         [ +  + ]:        146 :   if (qq.isConst())
      73                 :            :   {
      74                 :            :     // trivial, do not use transition inference
      75                 :          2 :     return;
      76                 :            :   }
      77                 :            : 
      78                 :            :   // if we are doing invariant templates, then construct the template
      79         [ +  - ]:        144 :   Trace("sygus-si") << "- Do transition inference..." << std::endl;
      80                 :        144 :   d_ti.process(qq, q[0][0]);
      81         [ +  - ]:        144 :   Trace("cegqi-inv") << std::endl;
      82                 :        144 :   Node prog = d_ti.getFunction();
      83         [ +  + ]:        144 :   if (!d_ti.isComplete())
      84                 :            :   {
      85                 :            :     // the invariant could not be inferred
      86                 :        100 :     return;
      87                 :            :   }
      88 [ -  + ][ -  + ]:         44 :   Assert(prog == q[0][0]);
                 [ -  - ]
      89                 :         44 :   NodeManager* nm = nodeManager();
      90                 :            :   // map the program back via non-single invocation map
      91                 :         88 :   std::vector<Node> prog_templ_vars;
      92                 :         44 :   d_ti.getVariables(prog_templ_vars);
      93                 :         44 :   d_trans_pre[prog] = d_ti.getPreCondition();
      94                 :         44 :   d_trans_post[prog] = d_ti.getPostCondition();
      95         [ +  - ]:         44 :   Trace("cegqi-inv") << "   precondition : " << d_trans_pre[prog] << std::endl;
      96         [ +  - ]:         44 :   Trace("cegqi-inv") << "  postcondition : " << d_trans_post[prog] << std::endl;
      97                 :            : 
      98                 :            :   // construct template argument
      99                 :         88 :   TypeNode atn = prog.getType();
     100         [ +  - ]:         44 :   if (atn.isFunction())
     101                 :            :   {
     102                 :         44 :     atn = atn.getRangeType();
     103                 :            :   }
     104                 :         44 :   d_templ_arg[prog] = NodeManager::mkDummySkolem("I", atn);
     105                 :            : 
     106                 :            :   // construct template
     107                 :         88 :   Node templ;
     108         [ +  - ]:         44 :   if (options().quantifiers.sygusInvAutoUnfold)
     109                 :            :   {
     110         [ +  - ]:         44 :     if (d_ti.isComplete())
     111                 :            :     {
     112         [ +  - ]:         88 :       Trace("cegqi-inv-auto-unfold")
     113                 :         44 :           << "Automatic deterministic unfolding... " << std::endl;
     114                 :            :       // auto-unfold
     115                 :         88 :       DetTrace dt;
     116                 :         44 :       int init_dt = d_ti.initializeTrace(dt);
     117         [ +  + ]:         44 :       if (init_dt == 0)
     118                 :            :       {
     119         [ +  - ]:         10 :         Trace("cegqi-inv-auto-unfold") << "  Init : ";
     120                 :         10 :         dt.print("cegqi-inv-auto-unfold");
     121         [ +  - ]:         10 :         Trace("cegqi-inv-auto-unfold") << std::endl;
     122                 :         10 :         unsigned counter = 0;
     123                 :         10 :         unsigned status = 0;
     124 [ +  + ][ +  + ]:        634 :         while (counter < 100 && status == 0)
     125                 :            :         {
     126                 :        624 :           status = d_ti.incrementTrace(dt);
     127                 :        624 :           counter++;
     128         [ +  - ]:        624 :           Trace("cegqi-inv-auto-unfold") << "  #" << counter << " : ";
     129                 :        624 :           dt.print("cegqi-inv-auto-unfold");
     130         [ +  - ]:       1248 :           Trace("cegqi-inv-auto-unfold")
     131                 :        624 :               << "...status = " << status << std::endl;
     132                 :            :         }
     133         [ +  + ]:         10 :         if (status == 1)
     134                 :            :         {
     135                 :            :           // we have a trivial invariant
     136                 :          4 :           templ = d_ti.constructFormulaTrace(dt);
     137         [ +  - ]:          8 :           Trace("cegqi-inv") << "By finite deterministic terminating trace, a "
     138                 :          0 :                                 "solution invariant is : "
     139                 :          4 :                              << std::endl;
     140         [ +  - ]:          4 :           Trace("cegqi-inv") << "   " << templ << std::endl;
     141                 :            :           // this should be unnecessary
     142                 :          4 :           templ = nm->mkNode(Kind::AND, templ, d_templ_arg[prog]);
     143                 :            :         }
     144                 :            :       }
     145                 :            :       else
     146                 :            :       {
     147         [ +  - ]:         34 :         Trace("cegqi-inv-auto-unfold") << "...failed initialize." << std::endl;
     148                 :            :       }
     149                 :            :     }
     150                 :            :   }
     151         [ +  - ]:         88 :   Trace("cegqi-inv") << "Make the template... " << tmode << " " << templ
     152                 :         44 :                      << std::endl;
     153         [ +  + ]:         44 :   if (templ.isNull())
     154                 :            :   {
     155         [ -  + ]:         40 :     if (tmode == options::SygusInvTemplMode::PRE)
     156                 :            :     {
     157                 :          0 :       templ = nm->mkNode(Kind::OR, d_trans_pre[prog], d_templ_arg[prog]);
     158                 :            :     }
     159                 :            :     else
     160                 :            :     {
     161 [ -  + ][ -  + ]:         40 :       Assert(tmode == options::SygusInvTemplMode::POST);
                 [ -  - ]
     162                 :         40 :       templ = nm->mkNode(Kind::AND, d_trans_post[prog], d_templ_arg[prog]);
     163                 :            :     }
     164                 :            :   }
     165         [ +  - ]:         88 :   Trace("cegqi-inv") << "       template (pre-substitution) : " << templ
     166                 :         44 :                      << std::endl;
     167 [ -  + ][ -  + ]:         44 :   Assert(!templ.isNull());
                 [ -  - ]
     168                 :            : 
     169                 :            :   // get the variables
     170                 :         88 :   Node sfvl = SygusUtils::getOrMkSygusArgumentList(prog);
     171         [ +  - ]:         44 :   if (!sfvl.isNull())
     172                 :            :   {
     173                 :         44 :     std::vector<Node> prog_vars(sfvl.begin(), sfvl.end());
     174                 :            :     // subsitute the template arguments
     175         [ +  - ]:         88 :     Trace("cegqi-inv") << "vars : " << prog_templ_vars << " " << prog_vars
     176                 :         44 :                        << std::endl;
     177 [ -  + ][ -  + ]:         44 :     Assert(prog_templ_vars.size() == prog_vars.size());
                 [ -  - ]
     178                 :         88 :     templ = templ.substitute(prog_templ_vars.begin(),
     179                 :            :                              prog_templ_vars.end(),
     180                 :            :                              prog_vars.begin(),
     181                 :         44 :                              prog_vars.end());
     182                 :            :   }
     183         [ +  - ]:         44 :   Trace("cegqi-inv") << "       template : " << templ << std::endl;
     184                 :         44 :   d_templ[prog] = templ;
     185                 :            : }
     186                 :            : 
     187                 :       4180 : Node SygusTemplateInfer::getTemplate(Node prog) const
     188                 :            : {
     189                 :       4180 :   std::map<Node, Node>::const_iterator tmpl = d_templ.find(prog);
     190         [ +  + ]:       4180 :   if (tmpl != d_templ.end())
     191                 :            :   {
     192                 :         77 :     return tmpl->second;
     193                 :            :   }
     194                 :       4103 :   return Node::null();
     195                 :            : }
     196                 :            : 
     197                 :         77 : Node SygusTemplateInfer::getTemplateArg(Node prog) const
     198                 :            : {
     199                 :         77 :   std::map<Node, Node>::const_iterator tmpla = d_templ_arg.find(prog);
     200         [ +  - ]:         77 :   if (tmpla != d_templ_arg.end())
     201                 :            :   {
     202                 :         77 :     return tmpla->second;
     203                 :            :   }
     204                 :          0 :   return Node::null();
     205                 :            : }
     206                 :            : 
     207                 :            : }  // namespace quantifiers
     208                 :            : }  // namespace theory
     209                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14