const std::vector<theory::SkolemLemma>& ppLemmas,
bool removable)
{
- if (!trn.isNull())
- {
- assertTrustedLemmaInternal(trn, removable);
- }
- for (const theory::SkolemLemma& lem : ppLemmas)
- {
- assertTrustedLemmaInternal(lem.d_lemma, removable);
- }
- // assert to decision engine
+ // Assert to decision engine. Notice this must come before the calls to
+ // assertTrustedLemmaInternal below, since the decision engine requires
+ // setting up information about the relevance of skolems before literals
+ // are potentially asserted to the theory engine, which it listens to for
+ // tracking active skolem definitions.
if (!removable)
{
// also add to the decision engine, where notice we don't need proofs
d_theoryProxy->notifyAssertion(lem.getProven(), lem.d_skolem, true);
}
}
+ if (!trn.isNull())
+ {
+ assertTrustedLemmaInternal(trn, removable);
+ }
+ for (const theory::SkolemLemma& lem : ppLemmas)
+ {
+ assertTrustedLemmaInternal(lem.d_lemma, removable);
+ }
}
void PropEngine::requirePhase(TNode n, bool phase) {
#include "prop/skolem_def_manager.h"
-#include "expr/attribute.h"
-
namespace cvc5 {
namespace prop {
SkolemDefManager::SkolemDefManager(context::Context* context,
context::UserContext* userContext)
- : d_skDefs(userContext), d_skActive(context)
+ : d_skDefs(userContext), d_skActive(context), d_hasSkolems(userContext)
{
}
// equivalent up to purification
if (d_skDefs.find(skolem) == d_skDefs.end())
{
+ // should not have already computed whether the skolem has skolems, or else
+ // our computation of hasSkolems is wrong after adding this definition
+ Assert(d_hasSkolems.find(skolem) == d_hasSkolems.end());
d_skDefs.insert(skolem, def);
}
}
{
std::unordered_set<Node> skolems;
getSkolems(literal, skolems);
+ Trace("sk-defs") << "notifyAsserted: " << literal << " has skolems "
+ << skolems << std::endl;
for (const Node& k : skolems)
{
if (d_skActive.find(k) != d_skActive.end())
continue;
}
d_skActive.insert(k);
+ Trace("sk-defs") << "...activate " << k << std::endl;
if (useDefs)
{
// add its definition to the activated list
}
}
-struct HasSkolemTag
-{
-};
-struct HasSkolemComputedTag
-{
-};
-/** Attribute true for nodes with skolems in them */
-typedef expr::Attribute<HasSkolemTag, bool> HasSkolemAttr;
-/** Attribute true for nodes where we have computed the above attribute */
-typedef expr::Attribute<HasSkolemComputedTag, bool> HasSkolemComputedAttr;
-
-bool SkolemDefManager::hasSkolems(TNode n) const
+bool SkolemDefManager::hasSkolems(TNode n)
{
+ Trace("sk-defs-debug") << "Compute has skolems for " << n << std::endl;
std::unordered_set<TNode> visited;
std::unordered_set<TNode>::iterator it;
+ NodeBoolMap::const_iterator itn;
std::vector<TNode> visit;
TNode cur;
visit.push_back(n);
do
{
cur = visit.back();
- if (cur.getAttribute(HasSkolemComputedAttr()))
+ itn = d_hasSkolems.find(cur);
+ if (itn != d_hasSkolems.end())
{
visit.pop_back();
// already computed
{
hasSkolem = (d_skDefs.find(cur) != d_skDefs.end());
}
- cur.setAttribute(HasSkolemAttr(), hasSkolem);
- cur.setAttribute(HasSkolemComputedAttr(), true);
+ d_hasSkolems[cur] = hasSkolem;
}
else
{
visit.pop_back();
bool hasSkolem;
if (cur.getMetaKind() == kind::metakind::PARAMETERIZED
- && cur.getOperator().getAttribute(HasSkolemAttr()))
+ && d_hasSkolems[cur.getOperator()])
{
hasSkolem = true;
}
hasSkolem = false;
for (TNode i : cur)
{
- Assert(i.getAttribute(HasSkolemComputedAttr()));
- if (i.getAttribute(HasSkolemAttr()))
+ Assert(d_hasSkolems.find(i) != d_hasSkolems.end());
+ if (d_hasSkolems[i])
{
hasSkolem = true;
break;
}
}
}
- cur.setAttribute(HasSkolemAttr(), hasSkolem);
- cur.setAttribute(HasSkolemComputedAttr(), true);
+ d_hasSkolems[cur] = hasSkolem;
}
} while (!visit.empty());
- Assert(n.getAttribute(HasSkolemComputedAttr()));
- return n.getAttribute(HasSkolemAttr());
+ Assert(d_hasSkolems.find(n) != d_hasSkolems.end());
+ return d_hasSkolems[n];
}
-void SkolemDefManager::getSkolems(TNode n,
- std::unordered_set<Node>& skolems) const
+void SkolemDefManager::getSkolems(TNode n, std::unordered_set<Node>& skolems)
{
std::unordered_set<TNode> visited;
std::unordered_set<TNode>::iterator it;
#include <unordered_set>
#include <vector>
+#include "context/cdhashmap.h"
#include "context/cdhashset.h"
#include "context/cdinsert_hashmap.h"
#include "context/context.h"
class SkolemDefManager
{
using NodeNodeMap = context::CDInsertHashMap<Node, Node>;
+ using NodeBoolMap = context::CDHashMap<Node, bool>;
using NodeSet = context::CDHashSet<Node>;
public:
* @param n The node to traverse
* @param skolems The set where the skolems are added
*/
- void getSkolems(TNode n, std::unordered_set<Node>& skolems) const;
- /** Does n have skolems having definitions managed by this class? */
- bool hasSkolems(TNode n) const;
+ void getSkolems(TNode n, std::unordered_set<Node>& skolems);
+ /**
+ * Does n have skolems having definitions managed by this class? Should call
+ * this method *after* notifying skolem definitions for all potential
+ * skolems occurring in n.
+ */
+ bool hasSkolems(TNode n);
private:
/** skolems to definitions (user-context dependent) */
NodeNodeMap d_skDefs;
/** set of active skolems (SAT-context dependent) */
NodeSet d_skActive;
+ /** Cache for hasSkolems */
+ NodeBoolMap d_hasSkolems;
};
} // namespace prop