Also adds substitutions as part of the output of -o learned-lits for completeness.
help = "print input literals that hold globally"
description = "With ``-o learned-lits``, cvc5 prints input literals that it has learned to hold globally."
example-file = "regress0/printer/learned-lit-output.smt2"
+[[option.mode.SUBS]]
+ name = "subs"
+ help = "print top-level substitutions learned during preprocessing"
+ description = "With ``-o subs``, cvc5 prints top-level substitutions learned during preprocessing."
+ example-file = "regress0/printer/subs-output.smt2"
# Stores then enabled output tags.
[[option]]
// Note that we don't have to keep rhs's in full solved form
// because SubstitutionMap::apply does a fixed-point iteration when
// substituting
- ttls.addSubstitutions(*newSubstitutions.get());
+ d_preprocContext->addSubstitutions(*newSubstitutions.get());
if (!learnedLitsToConjoin.empty())
{
#include "preprocessing/preprocessing_pass_context.h"
#include "expr/node_algorithm.h"
+#include "options/base_options.h"
#include "smt/env.h"
#include "theory/theory_engine.h"
#include "theory/theory_model.h"
return d_llm.getLearnedLiterals();
}
+void PreprocessingPassContext::printSubstitution(const Node& lhs,
+ const Node& rhs) const
+{
+ Node eq = lhs.eqNode(rhs);
+ output(OutputTag::LEARNED_LITS)
+ << "(learned-lit " << eq << " :preprocess-subs)" << std::endl;
+ output(OutputTag::SUBS) << "(substitution " << eq << ")" << std::endl;
+}
+
void PreprocessingPassContext::addSubstitution(const Node& lhs,
const Node& rhs,
ProofGenerator* pg)
{
- getTopLevelSubstitutions().addSubstitution(lhs, rhs, pg);
+ if (isOutputOn(OutputTag::LEARNED_LITS) || isOutputOn(OutputTag::SUBS))
+ {
+ printSubstitution(lhs, rhs);
+ }
+ d_env.getTopLevelSubstitutions().addSubstitution(lhs, rhs, pg);
}
void PreprocessingPassContext::addSubstitution(const Node& lhs,
PfRule id,
const std::vector<Node>& args)
{
- getTopLevelSubstitutions().addSubstitution(lhs, rhs, id, {}, args);
+ if (isOutputOn(OutputTag::LEARNED_LITS) || isOutputOn(OutputTag::SUBS))
+ {
+ printSubstitution(lhs, rhs);
+ }
+ d_env.getTopLevelSubstitutions().addSubstitution(lhs, rhs, id, {}, args);
+}
+
+void PreprocessingPassContext::addSubstitutions(
+ theory::TrustSubstitutionMap& tm)
+{
+ if (isOutputOn(OutputTag::LEARNED_LITS) || isOutputOn(OutputTag::SUBS))
+ {
+ std::unordered_map<Node, Node> subs = tm.get().getSubstitutions();
+ for (const std::pair<const Node, Node>& s : subs)
+ {
+ printSubstitution(s.first, s.second);
+ }
+ }
+ d_env.getTopLevelSubstitutions().addSubstitutions(tm);
}
} // namespace preprocessing
/** Spend resource in the resource manager of the associated Env. */
void spendResource(Resource r);
- /** Get a reference to the top-level substitution map */
+ /**
+ * Get a reference to the top-level substitution map. Note that all
+ * substitutions added to this map should use the addSubstitution methods
+ * below for the purposes of proper debugging information.
+ */
theory::TrustSubstitutionMap& getTopLevelSubstitutions() const;
/** Record symbols in assertions
const Node& rhs,
PfRule id,
const std::vector<Node>& args);
-
+ /** Add top level substitutions for a substitution map */
+ void addSubstitutions(theory::TrustSubstitutionMap& tm);
private:
+ /** Helper method for printing substitutions */
+ void printSubstitution(const Node& lhs, const Node& rhs) const;
+
/** Pointer to the theory engine associated with this context. */
TheoryEngine* d_theoryEngine;
/** Pointer to the prop engine associated with this context. */
{
}
+std::unordered_map<Node, Node> SubstitutionMap::getSubstitutions()
+{
+ std::unordered_map<Node, Node> subs;
+ for (const auto& sub : d_substitutions)
+ {
+ subs.emplace(sub.first, sub.second);
+ }
+ return subs;
+}
+
struct substitution_stack_element {
TNode d_node;
bool d_children_added;
void SubstitutionMap::addSubstitutions(SubstitutionMap& subMap, bool invalidateCache)
{
- SubstitutionMap::NodeMap::const_iterator it = subMap.begin();
- SubstitutionMap::NodeMap::const_iterator it_end = subMap.end();
+ NodeMap::const_iterator it = subMap.begin();
+ NodeMap::const_iterator it_end = subMap.end();
for (; it != it_end; ++ it) {
Assert(d_substitutions.find((*it).first) == d_substitutions.end());
d_substitutions[(*it).first] = (*it).second;
public:
SubstitutionMap(context::Context* context = nullptr);
+ /** Get substitutions in this object as a raw map */
+ std::unordered_map<Node, Node> getSubstitutions();
/**
* Adds a substitution from x to t.
*/
regress0/printer/empty_symbol_name.smt2
regress0/printer/learned-lit-output.smt2
regress0/printer/let_shadowing.smt2
+ regress0/printer/print_subs.smt2
regress0/printer/symbol_starting_w_digit.smt2
regress0/printer/tuples_and_records.cvc.smt2
regress0/proj-issue307-get-value-re.smt2
--- /dev/null
+; COMMAND-LINE: -o subs
+; EXPECT: (substitution (= a 3))
+; EXPECT: sat
+(set-logic ALL)
+(declare-fun a () Int)
+(declare-fun b () Int)
+(assert (= (* 2 a) 6))
+(assert (> b a))
+(check-sat)