GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers/fmf/first_order_model_fmc.cpp Lines: 70 70 100.0 %
Date: 2021-11-06 Branches: 124 250 49.6 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Aina Niemetz
4
 *
5
 * This file is part of the cvc5 project.
6
 *
7
 * Copyright (c) 2009-2021 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
 * Implementation of first order model for full model check.
14
 */
15
16
#include "theory/quantifiers/fmf/first_order_model_fmc.h"
17
18
#include "expr/attribute.h"
19
#include "expr/skolem_manager.h"
20
#include "theory/quantifiers/fmf/full_model_check.h"
21
#include "theory/rewriter.h"
22
23
using namespace cvc5::kind;
24
25
namespace cvc5 {
26
namespace theory {
27
namespace quantifiers {
28
namespace fmcheck {
29
30
/**
31
 * Marks that a term represents the entire domain of quantified formula for
32
 * the finite model finding fmc algorithm.
33
 */
34
struct IsStarAttributeId
35
{
36
};
37
using IsStarAttribute = expr::Attribute<IsStarAttributeId, bool>;
38
39
1560
FirstOrderModelFmc::FirstOrderModelFmc(Env& env,
40
                                       QuantifiersState& qs,
41
                                       QuantifiersRegistry& qr,
42
1560
                                       TermRegistry& tr)
43
1560
    : FirstOrderModel(env, qs, qr, tr)
44
{
45
1560
}
46
47
4680
FirstOrderModelFmc::~FirstOrderModelFmc()
48
{
49
2664
  for (std::pair<const Node, Def*>& d : d_models)
50
  {
51
1104
    delete d.second;
52
  }
53
3120
}
54
55
4254
void FirstOrderModelFmc::processInitialize(bool ispre)
56
{
57
4254
  if (!ispre)
58
  {
59
2127
    return;
60
  }
61
8336
  for (std::pair<const Node, Def*>& d : d_models)
62
  {
63
6209
    d.second->reset();
64
  }
65
}
66
67
162488
void FirstOrderModelFmc::processInitializeModelForTerm(Node n)
68
{
69
162488
  if (n.getKind() == APPLY_UF)
70
  {
71
    // cannot be a bound variable
72
55958
    Node op = n.getOperator();
73
27979
    if (op.getKind() != BOUND_VARIABLE)
74
    {
75
27343
      if (d_models.find(op) == d_models.end())
76
      {
77
1104
        d_models[op] = new Def;
78
      }
79
    }
80
  }
81
162488
}
82
83
2143037
bool FirstOrderModelFmc::isStar(Node n)
84
{
85
2143037
  return n.getAttribute(IsStarAttribute());
86
}
87
88
857943
Node FirstOrderModelFmc::getStar(TypeNode tn)
89
{
90
857943
  std::map<TypeNode, Node>::iterator it = d_type_star.find(tn);
91
857943
  if (it != d_type_star.end())
92
  {
93
857120
    return it->second;
94
  }
95
823
  SkolemManager* sm = NodeManager::currentNM()->getSkolemManager();
96
  Node st =
97
1646
      sm->mkDummySkolem("star", tn, "skolem created for full-model checking");
98
823
  d_type_star[tn] = st;
99
823
  st.setAttribute(IsStarAttribute(), true);
100
823
  return st;
101
}
102
103
7313
Node FirstOrderModelFmc::getFunctionValue(Node op, const char* argPrefix)
104
{
105
7313
  Trace("fmc-model") << "Get function value for " << op << std::endl;
106
7313
  NodeManager* nm = NodeManager::currentNM();
107
14626
  TypeNode type = op.getType();
108
14626
  std::vector<Node> vars;
109
19457
  for (size_t i = 0, nargs = type.getNumChildren() - 1; i < nargs; i++)
110
  {
111
24288
    std::stringstream ss;
112
12144
    ss << argPrefix << (i + 1);
113
24288
    Node b = nm->mkBoundVar(ss.str(), type[i]);
114
12144
    vars.push_back(b);
115
  }
116
14626
  Node boundVarList = nm->mkNode(BOUND_VAR_LIST, vars);
117
14626
  Node curr;
118
7313
  Def* odef = d_models[op];
119
24413
  for (size_t i = 0, ncond = odef->d_cond.size(); i < ncond; i++)
120
  {
121
17100
    size_t ii = (ncond - 1) - i;
122
34200
    Node v = odef->d_value[ii];
123
17100
    Trace("fmc-model-func") << "Value is : " << v << std::endl;
124
17100
    Assert(v.isConst());
125
17100
    if (curr.isNull())
126
    {
127
7313
      Trace("fmc-model-func") << "base : " << v << std::endl;
128
7313
      curr = v;
129
    }
130
    else
131
    {
132
      // make the condition
133
19574
      Node cond = odef->d_cond[ii];
134
9787
      Trace("fmc-model-func") << "...cond : " << cond << std::endl;
135
19574
      std::vector<Node> children;
136
29441
      for (size_t j = 0, nchild = cond.getNumChildren(); j < nchild; j++)
137
      {
138
39308
        TypeNode tn = vars[j].getType();
139
19654
        if (!isStar(cond[j]))
140
        {
141
39308
          Node c = getRepresentative(cond[j]);
142
19654
          c = getRepresentative(c);
143
19654
          children.push_back(nm->mkNode(EQUAL, vars[j], c));
144
        }
145
      }
146
9787
      Assert(!children.empty());
147
19574
      Node cc = nm->mkAnd(children);
148
149
19574
      Trace("fmc-model-func")
150
9787
          << "condition : " << cc << ", value : " << v << std::endl;
151
9787
      curr = nm->mkNode(ITE, cc, v, curr);
152
    }
153
  }
154
7313
  Trace("fmc-model") << "Made " << curr << " for " << op << std::endl;
155
7313
  curr = rewrite(curr);
156
14626
  return nm->mkNode(LAMBDA, boundVarList, curr);
157
}
158
159
}  // namespace fmcheck
160
}  // namespace quantifiers
161
}  // namespace theory
162
31137
}  // namespace cvc5