carl  24.04
Computer ARithmetic Library
Negations.h
Go to the documentation of this file.
1 #pragma once
2 
3 namespace carl {
4 
5 /**
6  * Resolves the outermost negation of this formula.
7  * @param _keepConstraint A flag indicating whether to change constraints in order
8  * to resolve the negation in front of them, or to keep the constraints and leave
9  * the negation.
10  */
11 template<typename Pol>
12 Formula<Pol> resolve_negation( const Formula<Pol>& f, bool _keepConstraint = true, bool resolve_varcomp = false) {
13  if (resolve_varcomp && f.type() == FormulaType::VARCOMPARE && f.variable_comparison().negated()) {
14  return Formula<Pol>(f.variable_comparison().resolve_negation());
15  }
16  if( f.type() != FormulaType::NOT ) return f;
17  FormulaType newType = f.type();
18  switch( f.subformula().type() )
19  {
20  case FormulaType::BOOL:
21  return f;
22  case FormulaType::UEQ:
23  if( _keepConstraint )
24  return f;
25  else
26  {
27  const UEquality& ueq = f.subformula().u_equality();
28  return Formula<Pol>( ueq.lhs(), ueq.rhs(), !ueq.negated() );
29  }
31  {
32  const Constraint<Pol>& constraint = f.subformula().constraint();
33  if( _keepConstraint )
34  return f;
35  else
36  {
37  switch( constraint.relation() )
38  {
39  case Relation::EQ:
40  {
41  return Formula<Pol>( constraint.lhs(), Relation::NEQ );
42  }
43  case Relation::LEQ:
44  {
45  return Formula<Pol>( -constraint.lhs(), Relation::LESS );
46  }
47  case Relation::LESS:
48  {
49  return Formula<Pol>( -constraint.lhs(), Relation::LEQ );
50  }
51  case Relation::GEQ:
52  {
53  return Formula<Pol>( constraint.lhs(), Relation::LESS );
54  }
55  case Relation::GREATER:
56  {
57  return Formula<Pol>( constraint.lhs(), Relation::LEQ );
58  }
59  case Relation::NEQ:
60  {
61  return Formula<Pol>( constraint.lhs(), Relation::EQ );
62  }
63  default:
64  {
65  assert( false );
66  std::cerr << "Unexpected relation symbol!" << std::endl;
67  return f;
68  }
69  }
70  }
71  }
73  if (resolve_varcomp) {
74  return Formula<Pol>(f.subformula().variable_comparison().invert_relation());
75  } else {
76  return Formula<Pol>(f.subformula().variable_comparison().negation());
77  }
78  }
80  assert(false);
81  return Formula<Pol>();
82  }
86  }
87  case FormulaType::TRUE: // (not true) -> false
89  case FormulaType::FALSE: // (not false) -> true
91  case FormulaType::NOT: // (not (not phi)) -> phi
92  return f.subformula().subformula();
94  {
95  assert( f.subformula().size() == 2 );
96  // (not (implies lhs rhs)) -> (and lhs (not rhs))
97  Formulas<Pol> subFormulas;
98  subFormulas.push_back( f.subformula().premise() );
99  subFormulas.push_back( Formula<Pol>( NOT, f.subformula().conclusion() ) );
100  return Formula<Pol>( AND, move( subFormulas ) );
101  }
102  case FormulaType::ITE: // (not (ite cond then else)) -> (ite cond (not then) (not else))
103  {
104  return Formula<Pol>( ITE, {f.subformula().condition(), Formula<Pol>( NOT, f.subformula().first_case() ), Formula<Pol>( NOT, f.subformula().second_case() )} );
105  }
106  case FormulaType::IFF: // (not (iff phi_1 .. phi_n)) -> (and (or phi_1 .. phi_n) (or (not phi_1) .. (not phi_n)))
107  {
108  Formulas<Pol> subFormulasA;
109  Formulas<Pol> subFormulasB;
110  for( auto& subFormula : f.subformula().subformulas() )
111  {
112  subFormulasA.push_back( subFormula );
113  subFormulasB.push_back( Formula<Pol>( NOT, subFormula ) );
114  }
115  return Formula<Pol>( AND, {Formula<Pol>( OR, move( subFormulasA ) ), Formula<Pol>( OR, move( subFormulasB ) )} );
116  }
117  case FormulaType::XOR: // (not (xor phi_1 .. phi_n)) -> (xor (not phi_1) phi_2 .. phi_n)
118  {
119  auto subFormula = f.subformula().subformulas().begin();
120  Formulas<Pol> subFormulas;
121  subFormulas.push_back( Formula<Pol>( NOT, *subFormula ) );
122  ++subFormula;
123  for( ; subFormula != f.subformula().subformulas().end(); ++subFormula )
124  subFormulas.push_back( *subFormula );
125  return Formula<Pol>( XOR, move( subFormulas ) );
126  }
127  case FormulaType::AND: // (not (and phi_1 .. phi_n)) -> (or (not phi_1) .. (not phi_n))
128  newType = FormulaType::OR;
129  break;
130  case FormulaType::OR: // (not (or phi_1 .. phi_n)) -> (and (not phi_1) .. (not phi_n))
131  newType = FormulaType::AND;
132  break;
133  case FormulaType::EXISTS: // (not (exists (vars) phi)) -> (forall (vars) (not phi))
134  newType = FormulaType::FORALL;
135  break;
136  case FormulaType::FORALL: // (not (forall (vars) phi)) -> (exists (vars) (not phi))
137  newType = FormulaType::EXISTS;
138  break;
139  default:
140  assert( false );
141  std::cerr << "Unexpected type of formula!" << std::endl;
142  return f;
143  }
144  assert( newType != f.subformula().type() );
145  assert( f.subformula().type() == FormulaType::AND || f.subformula().type() == FormulaType::OR );
146  Formulas<Pol> subFormulas;
147  for( const Formula<Pol>& subsubformula : f.subformula().subformulas() )
148  subFormulas.push_back( Formula<Pol>( FormulaType::NOT, subsubformula ) );
149  return Formula<Pol>( newType, move( subFormulas ) );
150 }
151 
152 }
carl is the main namespace for the library.
FormulaType
Represent the type of a formula to allow faster/specialized processing.
@ CONSTRAINT
@ BITVECTOR
@ VARCOMPARE
@ VARASSIGN
std::vector< Formula< Poly > > Formulas
Formula< Pol > resolve_negation(const Formula< Pol > &f, bool _keepConstraint=true, bool resolve_varcomp=false)
Resolves the outermost negation of this formula.
Definition: Negations.h:12
Relation inverse(Relation r)
Inverts the given relation symbol.
Definition: Relation.h:40
@ GREATER
Definition: SignCondition.h:15
Represent a polynomial (in)equality against zero.
Definition: Constraint.h:62
Relation relation() const
Definition: Constraint.h:116
const Pol & lhs() const
Definition: Constraint.h:109
const BVTerm & rhs() const
Definition: BVConstraint.h:62
const BVTerm & lhs() const
Definition: BVConstraint.h:55
BVCompareRelation relation() const
Definition: BVConstraint.h:69
static BVConstraint create(bool _consistent=true)
Represent an SMT formula, which can be an atom for some background theory or a boolean combination of...
Definition: Formula.h:47
const Formula & subformula() const
Definition: Formula.h:327
const VariableComparison< Pol > & variable_comparison() const
Definition: Formula.h:416
const Formula & premise() const
Definition: Formula.h:336
const Formula & conclusion() const
Definition: Formula.h:345
const Constraint< Pol > & constraint() const
Definition: Formula.h:410
const Formulas< Pol > & subformulas() const
Definition: Formula.h:400
const Formula & first_case() const
Definition: Formula.h:363
size_t size() const
Definition: Formula.h:455
const Formula & second_case() const
Definition: Formula.h:372
const BVConstraint & bv_constraint() const
Definition: Formula.h:426
const UEquality & u_equality() const
Definition: Formula.h:446
FormulaType type() const
Definition: Formula.h:254
Implements an uninterpreted equality, that is an equality of either two uninterpreted function instan...
Definition: UEquality.h:23
const UTerm & rhs() const
Definition: UEquality.h:79
bool negated() const
Definition: UEquality.h:65
const UTerm & lhs() const
Definition: UEquality.h:72