@@ -72,21 +72,60 @@ bool simplify_exprt::simplify_boolean(exprt &expr)
7272 return false ;
7373 }
7474 }
75- else if (expr.id ()==ID_or ||
76- expr.id ()==ID_and ||
77- expr.id ()==ID_xor)
75+ else if (expr.id ()==ID_xor)
7876 {
79- if (operands.empty ())
80- return true ;
81-
8277 bool result=true ;
8378
84- exprt::operandst::const_iterator last;
85- bool last_set=false ;
86-
8779 bool negate=false ;
8880
89- for (exprt::operandst::iterator it=operands.begin ();
81+ for (exprt::operandst::const_iterator it=operands.begin ();
82+ it!=operands.end ();)
83+ {
84+ if (it->type ().id ()!=ID_bool)
85+ return true ;
86+
87+ bool erase;
88+
89+ if (it->is_true ())
90+ {
91+ erase=true ;
92+ negate=!negate;
93+ }
94+ else
95+ erase=it->is_false ();
96+
97+ if (erase)
98+ {
99+ it=operands.erase (it);
100+ result=false ;
101+ }
102+ else
103+ it++;
104+ }
105+
106+ if (operands.empty ())
107+ {
108+ expr.make_bool (negate);
109+ return false ;
110+ }
111+ else if (operands.size ()==1 )
112+ {
113+ exprt tmp (operands.front ());
114+ if (negate)
115+ tmp.make_not ();
116+ expr.swap (tmp);
117+ return false ;
118+ }
119+
120+ return result;
121+ }
122+ else if (expr.id ()==ID_and || expr.id ()==ID_or)
123+ {
124+ std::unordered_set<exprt, irep_hash> expr_set;
125+
126+ bool result=true ;
127+
128+ for (exprt::operandst::const_iterator it=operands.begin ();
90129 it!=operands.end ();)
91130 {
92131 if (it->type ().id ()!=ID_bool)
@@ -106,77 +145,37 @@ bool simplify_exprt::simplify_boolean(exprt &expr)
106145 return false ;
107146 }
108147
109- bool erase;
110-
111- if (expr.id ()==ID_and)
112- erase=is_true;
113- else if (is_true && expr.id ()==ID_xor)
114- {
115- erase=true ;
116- negate=!negate;
117- }
118- else
119- erase=is_false;
120-
121- if (last_set && *it==*last &&
122- (expr.id ()==ID_or || expr.id ()==ID_and))
123- erase=true ; // erase duplicate operands
148+ bool erase=
149+ (expr.id ()==ID_and ? is_true : is_false) ||
150+ !expr_set.insert (*it).second ;
124151
125152 if (erase)
126153 {
127154 it=operands.erase (it);
128155 result=false ;
129156 }
130157 else
131- {
132- last=it;
133- last_set=true ;
134158 it++;
135- }
136159 }
137160
138161 // search for a and !a
139- if (expr.id ()==ID_and || expr.id ()==ID_or)
140- {
141- // first gather all the a's with !a
142-
143- std::unordered_set<exprt, irep_hash> expr_set;
144-
145- forall_operands (it, expr)
146- if (it->id ()==ID_not &&
147- it->operands ().size ()==1 &&
148- it->type ().id ()==ID_bool)
149- expr_set.insert (it->op0 ());
150-
151- // now search for a
152-
153- if (!expr_set.empty ())
162+ for (const exprt &op : operands)
163+ if (op.id ()==ID_not &&
164+ op.operands ().size ()==1 &&
165+ op.type ().id ()==ID_bool &&
166+ expr_set.find (op.op0 ())!=expr_set.end ())
154167 {
155- forall_operands (it, expr)
156- {
157- if (it->id ()!=ID_not &&
158- expr_set.find (*it)!=expr_set.end ())
159- {
160- expr.make_bool (expr.id ()==ID_or);
161- return false ;
162- }
163- }
168+ expr.make_bool (expr.id ()==ID_or);
169+ return false ;
164170 }
165- }
166171
167172 if (operands.empty ())
168173 {
169- if (expr.id ()==ID_and || negate)
170- expr=true_exprt ();
171- else
172- expr=false_exprt ();
173-
174+ expr.make_bool (expr.id ()==ID_and);
174175 return false ;
175176 }
176177 else if (operands.size ()==1 )
177178 {
178- if (negate)
179- expr.op0 ().make_not ();
180179 exprt tmp (operands.front ());
181180 expr.swap (tmp);
182181 return false ;
0 commit comments