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-05-24 Branches: 124 252 49.2 %

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