{
TypeNode btn = nm->booleanType();
TypeNode tnv = nm->mkFunctionType(btn, tn);
- TypeNode btnv = nm->mkFunctionType(btn, btn);
+ TypeNode btnv = nm->mkFunctionType({btn, btn}, btn);
BitVector bv = n.getConst<BitVector>();
size_t w = bv.getSize();
Node ret = getSymbolInternal(k, btn, "bvn");
// currently unsupported
return n;
}
+ else if (k == BITVECTOR_BB_TERM)
+ {
+ TypeNode btn = nm->booleanType();
+ // (bbT t1 ... tn) is (bbT t1 (bbT t2 ... (bbT tn emptybv)))
+ // where notice that each bbT has a different type
+ Node curr = getNullTerminator(BITVECTOR_CONCAT, tn);
+ for (size_t i = 0, nchild = n.getNumChildren(); i < nchild; ++i)
+ {
+ TypeNode bvt = nm->mkBitVectorType(i + 1);
+ TypeNode ftype = nm->mkFunctionType({btn, curr.getType()}, bvt);
+ Node bbt = getSymbolInternal(k, ftype, "bbT");
+ curr = nm->mkNode(APPLY_UF, bbt, n[nchild - (i + 1)], curr);
+ }
+ return curr;
+ }
else if (k == SEP_NIL)
{
Node tnn = typeAsNode(convertType(tn));
bool LfscNodeConverter::shouldTraverse(Node n)
{
Kind k = n.getKind();
- // don't convert bound variable list directly
- if (k == BOUND_VAR_LIST)
+ // don't convert bound variable or instantiation pattern list directly
+ if (k == BOUND_VAR_LIST || k == INST_PATTERN_LIST)
{
return false;
}
#include "options/proof_options.h"
#include "proof/lazy_proof.h"
+#include "proof/lfsc/lfsc_printer.h"
#include "proof/proof_checker.h"
#include "proof/proof_node_algorithm.h"
#include "proof/proof_node_manager.h"
{
Assert(res.getKind() == EQUAL);
Assert(res[0].getOperator() == res[1].getOperator());
+ Trace("lfsc-pp-cong") << "Processing congruence for " << res << " "
+ << res[0].getKind() << std::endl;
// different for closures
if (res[0].isClosure())
{
// REFL step. Notice this may be for interpreted or uninterpreted
// function symbols.
Node op = d_tproc.getOperatorOfTerm(res[0]);
+ Trace("lfsc-pp-cong") << "Processing cong for op " << op << " "
+ << op.getType() << std::endl;
Assert(!op.isNull());
// initial base step is REFL
Node opEq = op.eqNode(op);
for (size_t i = 0; i < nchildren; i++)
{
size_t ii = (nchildren - 1) - i;
+ Node uop = op;
+ // special case: each bv concat in the chain has a different type,
+ // so remake the operator here.
+ if (k == kind::BITVECTOR_CONCAT)
+ {
+ // we get the operator of the next argument concatenated with the
+ // current accumulated remainder.
+ Node currApp =
+ nm->mkNode(kind::BITVECTOR_CONCAT, children[ii][0], currEq[0]);
+ uop = d_tproc.getOperatorOfTerm(currApp);
+ }
Node argAppEq =
- nm->mkNode(HO_APPLY, op, children[ii][0])
- .eqNode(nm->mkNode(HO_APPLY, op, children[ii][1]));
+ nm->mkNode(HO_APPLY, uop, children[ii][0])
+ .eqNode(nm->mkNode(HO_APPLY, uop, children[ii][1]));
addLfscRule(cdp, argAppEq, {opEq, children[ii]}, LfscRule::CONG, {});
// now, congruence to the current equality
Node nextEq;