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