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-07 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
1559
FirstOrderModelFmc::FirstOrderModelFmc(Env& env,
40
                                       QuantifiersState& qs,
41
                                       QuantifiersRegistry& qr,
42
1559
                                       TermRegistry& tr)
43
1559
    : FirstOrderModel(env, qs, qr, tr)
44
{
45
1559
}
46
47
4677
FirstOrderModelFmc::~FirstOrderModelFmc()
48
{
49
2657
  for (std::pair<const Node, Def*>& d : d_models)
50
  {
51
1098
    delete d.second;
52
  }
53
3118
}
54
55
4242
void FirstOrderModelFmc::processInitialize(bool ispre)
56
{
57
4242
  if (!ispre)
58
  {
59
2121
    return;
60
  }
61
8309
  for (std::pair<const Node, Def*>& d : d_models)
62
  {
63
6188
    d.second->reset();
64
  }
65
}
66
67
161635
void FirstOrderModelFmc::processInitializeModelForTerm(Node n)
68
{
69
161635
  if (n.getKind() == APPLY_UF)
70
  {
71
    // cannot be a bound variable
72
55872
    Node op = n.getOperator();
73
27936
    if (op.getKind() != BOUND_VARIABLE)
74
    {
75
27300
      if (d_models.find(op) == d_models.end())
76
      {
77
1098
        d_models[op] = new Def;
78
      }
79
    }
80
  }
81
161635
}
82
83
2134951
bool FirstOrderModelFmc::isStar(Node n)
84
{
85
2134951
  return n.getAttribute(IsStarAttribute());
86
}
87
88
854479
Node FirstOrderModelFmc::getStar(TypeNode tn)
89
{
90
854479
  std::map<TypeNode, Node>::iterator it = d_type_star.find(tn);
91
854479
  if (it != d_type_star.end())
92
  {
93
853657
    return it->second;
94
  }
95
822
  SkolemManager* sm = NodeManager::currentNM()->getSkolemManager();
96
  Node st =
97
1644
      sm->mkDummySkolem("star", tn, "skolem created for full-model checking");
98
822
  d_type_star[tn] = st;
99
822
  st.setAttribute(IsStarAttribute(), true);
100
822
  return st;
101
}
102
103
7286
Node FirstOrderModelFmc::getFunctionValue(Node op, const char* argPrefix)
104
{
105
7286
  Trace("fmc-model") << "Get function value for " << op << std::endl;
106
7286
  NodeManager* nm = NodeManager::currentNM();
107
14572
  TypeNode type = op.getType();
108
14572
  std::vector<Node> vars;
109
19403
  for (size_t i = 0, nargs = type.getNumChildren() - 1; i < nargs; i++)
110
  {
111
24234
    std::stringstream ss;
112
12117
    ss << argPrefix << (i + 1);
113
24234
    Node b = nm->mkBoundVar(ss.str(), type[i]);
114
12117
    vars.push_back(b);
115
  }
116
14572
  Node boundVarList = nm->mkNode(BOUND_VAR_LIST, vars);
117
14572
  Node curr;
118
7286
  Def* odef = d_models[op];
119
24338
  for (size_t i = 0, ncond = odef->d_cond.size(); i < ncond; i++)
120
  {
121
17052
    size_t ii = (ncond - 1) - i;
122
34104
    Node v = odef->d_value[ii];
123
17052
    Trace("fmc-model-func") << "Value is : " << v << std::endl;
124
17052
    Assert(v.isConst());
125
17052
    if (curr.isNull())
126
    {
127
7286
      Trace("fmc-model-func") << "base : " << v << std::endl;
128
7286
      curr = v;
129
    }
130
    else
131
    {
132
      // make the condition
133
19532
      Node cond = odef->d_cond[ii];
134
9766
      Trace("fmc-model-func") << "...cond : " << cond << std::endl;
135
19532
      std::vector<Node> children;
136
29399
      for (size_t j = 0, nchild = cond.getNumChildren(); j < nchild; j++)
137
      {
138
39266
        TypeNode tn = vars[j].getType();
139
19633
        if (!isStar(cond[j]))
140
        {
141
39266
          Node c = getRepresentative(cond[j]);
142
19633
          c = getRepresentative(c);
143
19633
          children.push_back(nm->mkNode(EQUAL, vars[j], c));
144
        }
145
      }
146
9766
      Assert(!children.empty());
147
19532
      Node cc = nm->mkAnd(children);
148
149
19532
      Trace("fmc-model-func")
150
9766
          << "condition : " << cc << ", value : " << v << std::endl;
151
9766
      curr = nm->mkNode(ITE, cc, v, curr);
152
    }
153
  }
154
7286
  Trace("fmc-model") << "Made " << curr << " for " << op << std::endl;
155
7286
  curr = rewrite(curr);
156
14572
  return nm->mkNode(LAMBDA, boundVarList, curr);
157
}
158
159
}  // namespace fmcheck
160
}  // namespace quantifiers
161
}  // namespace theory
162
31137
}  // namespace cvc5