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