3 #include <carl-arith/core/Variable.h>
4 #include <carl-formula/formula/Formula.h>
5 #include <carl-formula/formula/functions/Variables.h>
31 return "GreedyMaxUnivariate";
33 return "FeatureBased";
35 return "FeatureBasedZ3";
37 return "FeatureBasedBrown";
39 return "FeatureBasedTriangular";
41 return "FeatureBasedLexicographic";
43 return "FeatureBasedPickering";
45 return "EarliestSplitting";
53 using carl::operator<<;
66 template<mcsat::VariableOrdering vo>
68 boost::container::flat_map<carl::Variable, size_t> quantifier_block_index;
69 for (
auto v : formula.variables()) {
70 if (std::find_if(quantifiers.begin(), quantifiers.end(), [v](
const auto& e) { return e.second == v; }) == quantifiers.end()) {
71 quantifier_block_index[v] = 0;
75 if (!quantifier_block_index.empty()) i++;
76 carl::Quantifier last = carl::Quantifier::FREE;
77 for (
const auto& e : quantifiers) {
78 assert(e.first != carl::Quantifier::FREE);
79 if (last != e.first && last != carl::Quantifier::FREE) i++;
80 quantifier_block_index[e.second] = i;
85 std::vector<ConstraintT> constraints;
86 carl::arithmetic_constraints(formula, constraints);
87 std::vector<carl::Variable>
result = mcsat::calculate_variable_order<vo>(constraints);
91 std::stable_sort(
result.begin(),
result.end(), [&quantifier_block_index](
const auto& lhs,
const auto& rhs) {
92 return quantifier_block_index.at(lhs) < quantifier_block_index.at(rhs);
114 std::vector<FormulaT> subformulas;
116 while (subformulas.empty()) {
117 if (formula.is_atom()) {
119 return impl::variable_ordering<mcsat::VariableOrdering::FeatureBasedBrown>(
prefix, base_formula);
122 formula = formula.subformula();
124 assert(formula.is_nary());
125 subformulas = formula.subformulas();
129 std::vector<boost::container::flat_set<carl::Variable>> quantifiers;
130 quantifiers.emplace_back();
131 for (
auto v : base_formula.variables()) {
132 if (std::find_if(
prefix.begin(),
prefix.end(), [v](
const auto& e) { return e.second == v; }) ==
prefix.end()) {
133 quantifiers.back().insert(v);
136 if (quantifiers.back().empty()) quantifiers.pop_back();
137 carl::Quantifier last = carl::Quantifier::FREE;
138 for (
const auto& e :
prefix) {
139 assert(e.first != carl::Quantifier::FREE);
140 if (last != e.first && last != carl::Quantifier::FREE) quantifiers.emplace_back();
141 quantifiers.back().insert(e.second);
145 std::vector<carl::Variables> shared_subformula_variables;
146 for (
size_t i = 0; i < subformulas.size() - 1; i++) {
147 for (
size_t j = i + 1; j < subformulas.size(); j++) {
148 auto& lhs = subformulas[i].variables();
149 auto& rhs = subformulas[j].variables();
150 carl::Variables shared;
151 std::set_intersection(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), std::inserter(shared, shared.begin()));
152 shared_subformula_variables.push_back(shared);
157 auto deleteVariable = [&shared_subformula_variables](
const carl::Variable&
var) ->
void {
158 for (
auto& shared : shared_subformula_variables) {
162 shared_subformula_variables.erase(std::remove_if(shared_subformula_variables.begin(), shared_subformula_variables.end(), [](
const auto& set) { return set.empty(); }), shared_subformula_variables.end());
166 auto getInfo = [&shared_subformula_variables](
const carl::Variable&
var) -> std::pair<size_t, size_t> {
168 size_t min_shared_size = std::numeric_limits<size_t>::max();
169 for (
const auto& shared : shared_subformula_variables) {
170 if (shared.find(
var) != shared.end()) {
172 min_shared_size = std::min(min_shared_size, shared.size());
179 std::vector<carl::Variable>
result;
182 std::vector<ConstraintT> constraints;
183 carl::arithmetic_constraints(formula, constraints);
186 for (
const auto& block : quantifiers) {
187 auto block_variables = block;
188 while(!block_variables.empty()) {
189 std::map<carl::Variable, std::pair<size_t, size_t>> variables_by_info;
190 for (
const auto&
var : block_variables) {
191 auto info = getInfo(
var);
192 variables_by_info[
var] = info;
194 SMTRAT_LOG_DEBUG(
"smtrat.covering_ng",
"Variables by info: " << variables_by_info)
196 std::pair<size_t, size_t> max_info = std::make_pair(std::numeric_limits<size_t>::min(), std::numeric_limits<size_t>::max());
197 carl::Variable max_var = carl::Variable::NO_VARIABLE;
198 for (
const auto& [
var, info] : variables_by_info) {
199 if (info.first > max_info.first) {
202 }
else if (info.first == max_info.first) {
203 if (info.second < max_info.second) {
209 SMTRAT_LOG_DEBUG(
"smtrat.covering_ng",
"Max var: " << max_var <<
" with info " << max_info)
210 if(max_var == carl::Variable::NO_VARIABLE){
212 for(
const auto&
var : unblocked_sorting){
213 if(block_variables.contains(
var)){
216 block_variables.erase(
var);
222 result.push_back(max_var);
224 deleteVariable(max_var);
225 block_variables.erase(max_var);
231 assert(
result.size() == formula.variables().size());
239 template<VariableOrderingHeuristics vo>
243 return impl::variable_ordering<mcsat::VariableOrdering::GreedyMaxUnivariate>(quantifiers, formula);
245 return impl::variable_ordering<mcsat::VariableOrdering::FeatureBased>(quantifiers, formula);
247 return impl::variable_ordering<mcsat::VariableOrdering::FeatureBasedZ3>(quantifiers, formula);
249 return impl::variable_ordering<mcsat::VariableOrdering::FeatureBasedBrown>(quantifiers, formula);
251 return impl::variable_ordering<mcsat::VariableOrdering::FeatureBasedTriangular>(quantifiers, formula);
253 return impl::variable_ordering<mcsat::VariableOrdering::FeatureBasedLexicographic>(quantifiers, formula);
255 return impl::variable_ordering<mcsat::VariableOrdering::FeatureBasedPickering>(quantifiers, formula);
std::vector< carl::Variable > variable_ordering(const carl::QuantifierPrefix &quantifiers, const FormulaT &formula)
Calculates a variable ordering based on the given quantifier blocks and the given formula.
std::vector< carl::Variable > sort_earliest_splitting(const carl::QuantifierPrefix &prefix, const FormulaT &base_formula)
Calculates a variable ordering based on the given quantifier blocks and the given formula.
std::vector< carl::Variable > get_variable_ordering(const carl::QuantifierPrefix &quantifiers, const FormulaT &formula)
VariableOrderingHeuristics
Possible heuristics for variable ordering.
@ FeatureBasedLexicographic
std::string get_name(VariableOrderingHeuristics ordering)
std::vector< T > prefix(const std::vector< T > vars, std::size_t prefixSize)
double num_occurrences(const Constraints &constraints, carl::Variable v)
std::vector< carl::Variable > greedy_max_univariate(const Constraints &c)
carl::Formula< Poly > FormulaT
#define SMTRAT_LOG_DEBUG(channel, msg)