1 /********************* */
2 /*! \file evaluator.cpp
4 ** Top contributors (to current version):
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2018 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.\endverbatim
12 ** \brief The Evaluator class
14 ** The Evaluator class.
17 #include "theory/evaluator.h"
19 #include "theory/bv/theory_bv_utils.h"
20 #include "theory/theory.h"
21 #include "util/integer.h"
26 EvalResult::EvalResult(const EvalResult
& other
)
31 case BOOL
: d_bool
= other
.d_bool
; break;
33 new (&d_bv
) BitVector
;
37 new (&d_rat
) Rational
;
48 EvalResult
& EvalResult::operator=(const EvalResult
& other
)
55 case BOOL
: d_bool
= other
.d_bool
; break;
57 new (&d_bv
) BitVector
;
61 new (&d_rat
) Rational
;
74 EvalResult::~EvalResult()
98 Node
EvalResult::toNode() const
100 NodeManager
* nm
= NodeManager::currentNM();
103 case EvalResult::BOOL
: return nm
->mkConst(d_bool
);
104 case EvalResult::BITVECTOR
: return nm
->mkConst(d_bv
);
105 case EvalResult::RATIONAL
: return nm
->mkConst(d_rat
);
106 case EvalResult::STRING
: return nm
->mkConst(d_str
);
109 Trace("evaluator") << "Missing conversion from " << d_tag
<< " to node"
118 Node
Evaluator::eval(TNode n
,
119 const std::vector
<Node
>& args
,
120 const std::vector
<Node
>& vals
)
122 Trace("evaluator") << "Evaluating " << n
<< " under substitution " << args
123 << " " << vals
<< std::endl
;
124 return evalInternal(n
, args
, vals
).toNode();
127 EvalResult
Evaluator::evalInternal(TNode n
,
128 const std::vector
<Node
>& args
,
129 const std::vector
<Node
>& vals
)
131 std::unordered_map
<TNode
, EvalResult
, TNodeHashFunction
> results
;
132 std::vector
<TNode
> queue
;
133 queue
.emplace_back(n
);
135 while (queue
.size() != 0)
137 TNode currNode
= queue
.back();
139 if (results
.find(currNode
) != results
.end())
146 for (const auto& currNodeChild
: currNode
)
148 if (results
.find(currNodeChild
) == results
.end())
150 queue
.emplace_back(currNodeChild
);
159 Node currNodeVal
= currNode
;
160 if (currNode
.isVar())
162 const auto& it
= std::find(args
.begin(), args
.end(), currNode
);
164 if (it
== args
.end())
169 ptrdiff_t pos
= std::distance(args
.begin(), it
);
170 currNodeVal
= vals
[pos
];
172 else if (currNode
.getKind() == kind::APPLY_UF
173 && currNode
.getOperator().getKind() == kind::LAMBDA
)
175 // Create a copy of the current substitutions
176 std::vector
<Node
> lambdaArgs(args
);
177 std::vector
<Node
> lambdaVals(vals
);
179 // Add the values for the arguments of the lambda as substitutions at
180 // the beginning of the vector to shadow variables from outer scopes
181 // with the same name
182 Node op
= currNode
.getOperator();
183 for (const auto& lambdaArg
: op
[0])
185 lambdaArgs
.insert(lambdaArgs
.begin(), lambdaArg
);
188 for (const auto& lambdaVal
: currNode
)
190 lambdaVals
.insert(lambdaVals
.begin(), results
[lambdaVal
].toNode());
193 // Lambdas are evaluated in a recursive fashion because each evaluation
194 // requires different substitutions
195 results
[currNode
] = evalInternal(op
[1], lambdaArgs
, lambdaVals
);
199 switch (currNodeVal
.getKind())
201 case kind::CONST_BOOLEAN
:
202 results
[currNode
] = EvalResult(currNodeVal
.getConst
<bool>());
207 results
[currNode
] = EvalResult(!(results
[currNode
[0]].d_bool
));
213 bool res
= results
[currNode
[0]].d_bool
;
214 for (size_t i
= 1, end
= currNode
.getNumChildren(); i
< end
; i
++)
216 res
= res
&& results
[currNode
[i
]].d_bool
;
218 results
[currNode
] = EvalResult(res
);
224 bool res
= results
[currNode
[0]].d_bool
;
225 for (size_t i
= 1, end
= currNode
.getNumChildren(); i
< end
; i
++)
227 res
= res
|| results
[currNode
[i
]].d_bool
;
229 results
[currNode
] = EvalResult(res
);
233 case kind::CONST_RATIONAL
:
235 const Rational
& r
= currNodeVal
.getConst
<Rational
>();
236 results
[currNode
] = EvalResult(r
);
242 Rational res
= results
[currNode
[0]].d_rat
;
243 for (size_t i
= 1, end
= currNode
.getNumChildren(); i
< end
; i
++)
245 res
= res
+ results
[currNode
[i
]].d_rat
;
247 results
[currNode
] = EvalResult(res
);
253 const Rational
& x
= results
[currNode
[0]].d_rat
;
254 const Rational
& y
= results
[currNode
[1]].d_rat
;
255 results
[currNode
] = EvalResult(x
- y
);
261 Rational res
= results
[currNode
[0]].d_rat
;
262 for (size_t i
= 1, end
= currNode
.getNumChildren(); i
< end
; i
++)
264 res
= res
* results
[currNode
[i
]].d_rat
;
266 results
[currNode
] = EvalResult(res
);
272 const Rational
& x
= results
[currNode
[0]].d_rat
;
273 const Rational
& y
= results
[currNode
[1]].d_rat
;
274 results
[currNode
] = EvalResult(x
>= y
);
278 case kind::CONST_STRING
:
279 results
[currNode
] = EvalResult(currNodeVal
.getConst
<String
>());
282 case kind::STRING_CONCAT
:
284 String res
= results
[currNode
[0]].d_str
;
285 for (size_t i
= 1, end
= currNode
.getNumChildren(); i
< end
; i
++)
287 res
= res
.concat(results
[currNode
[i
]].d_str
);
289 results
[currNode
] = EvalResult(res
);
293 case kind::STRING_LENGTH
:
295 const String
& s
= results
[currNode
[0]].d_str
;
296 results
[currNode
] = EvalResult(Rational(s
.size()));
300 case kind::STRING_SUBSTR
:
302 const String
& s
= results
[currNode
[0]].d_str
;
303 Integer
s_len(s
.size());
304 Integer i
= results
[currNode
[1]].d_rat
.getNumerator();
305 Integer j
= results
[currNode
[2]].d_rat
.getNumerator();
307 if (i
.strictlyNegative() || j
.strictlyNegative() || i
>= s_len
)
309 results
[currNode
] = EvalResult(String(""));
311 else if (i
+ j
> s_len
)
314 EvalResult(s
.suffix((s_len
- i
).toUnsignedInt()));
319 EvalResult(s
.substr(i
.toUnsignedInt(), j
.toUnsignedInt()));
324 case kind::STRING_CHARAT
:
326 const String
& s
= results
[currNode
[0]].d_str
;
327 Integer
s_len(s
.size());
328 Integer i
= results
[currNode
[1]].d_rat
.getNumerator();
329 if (i
.strictlyNegative() || i
>= s_len
)
331 results
[currNode
] = EvalResult(String(""));
335 results
[currNode
] = EvalResult(s
.substr(i
.toUnsignedInt(), 1));
340 case kind::STRING_STRCTN
:
342 const String
& s
= results
[currNode
[0]].d_str
;
343 const String
& t
= results
[currNode
[1]].d_str
;
344 results
[currNode
] = EvalResult(s
.find(t
) != std::string::npos
);
348 case kind::STRING_STRIDOF
:
350 const String
& s
= results
[currNode
[0]].d_str
;
351 Integer
s_len(s
.size());
352 const String
& x
= results
[currNode
[1]].d_str
;
353 Integer i
= results
[currNode
[2]].d_rat
.getNumerator();
355 if (i
.strictlyNegative() || i
>= s_len
)
357 results
[currNode
] = EvalResult(Rational(-1));
361 size_t r
= s
.find(x
, i
.toUnsignedInt());
362 if (r
== std::string::npos
)
364 results
[currNode
] = EvalResult(Rational(-1));
368 results
[currNode
] = EvalResult(Rational(r
));
374 case kind::STRING_STRREPL
:
376 const String
& s
= results
[currNode
[0]].d_str
;
377 const String
& x
= results
[currNode
[1]].d_str
;
378 const String
& y
= results
[currNode
[2]].d_str
;
379 results
[currNode
] = EvalResult(s
.replace(x
, y
));
383 case kind::STRING_PREFIX
:
385 const String
& t
= results
[currNode
[0]].d_str
;
386 const String
& s
= results
[currNode
[1]].d_str
;
387 if (s
.size() < t
.size())
389 results
[currNode
] = EvalResult(false);
393 results
[currNode
] = EvalResult(s
.prefix(t
.size()) == t
);
398 case kind::STRING_SUFFIX
:
400 const String
& t
= results
[currNode
[0]].d_str
;
401 const String
& s
= results
[currNode
[1]].d_str
;
402 if (s
.size() < t
.size())
404 results
[currNode
] = EvalResult(false);
408 results
[currNode
] = EvalResult(s
.suffix(t
.size()) == t
);
413 case kind::STRING_ITOS
:
415 Integer i
= results
[currNode
[0]].d_rat
.getNumerator();
416 if (i
.strictlyNegative())
418 results
[currNode
] = EvalResult(String(""));
422 results
[currNode
] = EvalResult(String(i
.toString()));
427 case kind::STRING_STOI
:
429 const String
& s
= results
[currNode
[0]].d_str
;
432 results
[currNode
] = EvalResult(Rational(-1));
436 results
[currNode
] = EvalResult(Rational(s
.toNumber()));
441 case kind::CONST_BITVECTOR
:
442 results
[currNode
] = EvalResult(currNodeVal
.getConst
<BitVector
>());
445 case kind::BITVECTOR_NOT
:
446 results
[currNode
] = EvalResult(~results
[currNode
[0]].d_bv
);
449 case kind::BITVECTOR_NEG
:
450 results
[currNode
] = EvalResult(-results
[currNode
[0]].d_bv
);
453 case kind::BITVECTOR_EXTRACT
:
455 unsigned lo
= bv::utils::getExtractLow(currNodeVal
);
456 unsigned hi
= bv::utils::getExtractHigh(currNodeVal
);
458 EvalResult(results
[currNode
[0]].d_bv
.extract(hi
, lo
));
462 case kind::BITVECTOR_CONCAT
:
464 BitVector res
= results
[currNode
[0]].d_bv
;
465 for (size_t i
= 1, end
= currNode
.getNumChildren(); i
< end
; i
++)
467 res
= res
.concat(results
[currNode
[i
]].d_bv
);
469 results
[currNode
] = EvalResult(res
);
473 case kind::BITVECTOR_PLUS
:
475 BitVector res
= results
[currNode
[0]].d_bv
;
476 for (size_t i
= 1, end
= currNode
.getNumChildren(); i
< end
; i
++)
478 res
= res
+ results
[currNode
[i
]].d_bv
;
480 results
[currNode
] = EvalResult(res
);
484 case kind::BITVECTOR_MULT
:
486 BitVector res
= results
[currNode
[0]].d_bv
;
487 for (size_t i
= 1, end
= currNode
.getNumChildren(); i
< end
; i
++)
489 res
= res
* results
[currNode
[i
]].d_bv
;
491 results
[currNode
] = EvalResult(res
);
494 case kind::BITVECTOR_AND
:
496 BitVector res
= results
[currNode
[0]].d_bv
;
497 for (size_t i
= 1, end
= currNode
.getNumChildren(); i
< end
; i
++)
499 res
= res
& results
[currNode
[i
]].d_bv
;
501 results
[currNode
] = EvalResult(res
);
505 case kind::BITVECTOR_OR
:
507 BitVector res
= results
[currNode
[0]].d_bv
;
508 for (size_t i
= 1, end
= currNode
.getNumChildren(); i
< end
; i
++)
510 res
= res
| results
[currNode
[i
]].d_bv
;
512 results
[currNode
] = EvalResult(res
);
516 case kind::BITVECTOR_XOR
:
518 BitVector res
= results
[currNode
[0]].d_bv
;
519 for (size_t i
= 1, end
= currNode
.getNumChildren(); i
< end
; i
++)
521 res
= res
^ results
[currNode
[i
]].d_bv
;
523 results
[currNode
] = EvalResult(res
);
529 EvalResult lhs
= results
[currNode
[0]];
530 EvalResult rhs
= results
[currNode
[1]];
534 case EvalResult::BOOL
:
536 results
[currNode
] = EvalResult(lhs
.d_bool
== rhs
.d_bool
);
540 case EvalResult::BITVECTOR
:
542 results
[currNode
] = EvalResult(lhs
.d_bv
== rhs
.d_bv
);
546 case EvalResult::RATIONAL
:
548 results
[currNode
] = EvalResult(lhs
.d_rat
== rhs
.d_rat
);
552 case EvalResult::STRING
:
554 results
[currNode
] = EvalResult(lhs
.d_str
== rhs
.d_str
);
560 Trace("evaluator") << "Theory " << Theory::theoryOf(currNode
[0])
561 << " not supported" << std::endl
;
572 if (results
[currNode
[0]].d_bool
)
574 results
[currNode
] = results
[currNode
[1]];
578 results
[currNode
] = results
[currNode
[2]];
585 Trace("evaluator") << "Kind " << currNodeVal
.getKind()
586 << " not supported" << std::endl
;
596 } // namespace theory