@@ -72,21 +72,60 @@ bool simplify_exprt::simplify_boolean(exprt &expr)
72
72
return false ;
73
73
}
74
74
}
75
- else if (expr.id ()==ID_or ||
76
- expr.id ()==ID_and ||
77
- expr.id ()==ID_xor)
75
+ else if (expr.id ()==ID_xor)
78
76
{
79
- if (operands.empty ())
80
- return true ;
81
-
82
77
bool result=true ;
83
78
84
- exprt::operandst::const_iterator last;
85
- bool last_set=false ;
86
-
87
79
bool negate=false ;
88
80
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 ();
90
129
it!=operands.end ();)
91
130
{
92
131
if (it->type ().id ()!=ID_bool)
@@ -106,77 +145,37 @@ bool simplify_exprt::simplify_boolean(exprt &expr)
106
145
return false ;
107
146
}
108
147
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 ;
124
151
125
152
if (erase)
126
153
{
127
154
it=operands.erase (it);
128
155
result=false ;
129
156
}
130
157
else
131
- {
132
- last=it;
133
- last_set=true ;
134
158
it++;
135
- }
136
159
}
137
160
138
161
// 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 ())
154
167
{
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 ;
164
170
}
165
- }
166
171
167
172
if (operands.empty ())
168
173
{
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);
174
175
return false ;
175
176
}
176
177
else if (operands.size ()==1 )
177
178
{
178
- if (negate)
179
- expr.op0 ().make_not ();
180
179
exprt tmp (operands.front ());
181
180
expr.swap (tmp);
182
181
return false ;
0 commit comments