@@ -146,31 +146,53 @@ Function: bmc_supports_SVA_property
146146
147147bool bmc_supports_SVA_property (const exprt &expr)
148148{
149- if (!is_temporal_operator (expr))
149+ // Define 'SVA unbounded temporal operators' as one of
150+ // * always (not: ranged_always)
151+ // * s_eventually without range (not: eventually, which is ranged)
152+ // * until, s_until, until_with, s_until_with
153+
154+ // We support
155+ // * formulas that contain no unbounded temporal operator
156+ // * always φ, where φ is a supported property
157+ // * s_eventually φ, where φ contains no unbounded temporal operator
158+ // * s_nexttime/nexttime φ, where φ is a supported property
159+ // * conjunctions and disjunctions of supported SVA properties
160+
161+ auto unbounded_operator = [](const exprt &expr)
150162 {
151- if (!has_temporal_operator (expr))
152- return true ; // initial state only
153- else if (
154- expr.id () == ID_and || expr.id () == ID_or || expr.id () == ID_implies)
155- {
156- for (auto &op : expr.operands ())
157- if (!bmc_supports_property (op))
158- return false ;
159- return true ;
160- }
161- else
162- return false ;
163+ return expr.id () == ID_sva_always || expr.id () == ID_sva_s_eventually ||
164+ expr.id () == ID_sva_until || expr.id () == ID_sva_s_until ||
165+ expr.id () == ID_sva_until_with || expr.id () == ID_sva_s_until_with;
166+ };
167+
168+ if (!has_subexpr (expr, unbounded_operator))
169+ {
170+ return true ;
171+ }
172+ else if (expr.id () == ID_sva_s_eventually)
173+ {
174+ return !has_subexpr (
175+ to_sva_s_eventually_expr (expr).op (), unbounded_operator);
163176 }
164- else if (expr.id () == ID_sva_cycle_delay)
165- return !has_temporal_operator (to_sva_cycle_delay_expr (expr).op ());
166- else if (expr.id () == ID_sva_nexttime)
167- return !has_temporal_operator (to_sva_nexttime_expr (expr).op ());
168177 else if (expr.id () == ID_sva_s_nexttime)
169- return !has_temporal_operator (to_sva_s_nexttime_expr (expr).op ());
178+ {
179+ return bmc_supports_SVA_property (to_sva_s_nexttime_expr (expr).op ());
180+ }
181+ else if (expr.id () == ID_sva_nexttime)
182+ {
183+ return bmc_supports_SVA_property (to_sva_nexttime_expr (expr).op ());
184+ }
170185 else if (expr.id () == ID_sva_always)
186+ {
187+ return bmc_supports_SVA_property (to_sva_always_expr (expr).op ());
188+ }
189+ else if (expr.id () == ID_and || expr.id () == ID_or)
190+ {
191+ for (auto &op : expr.operands ())
192+ if (!bmc_supports_SVA_property (op))
193+ return false ;
171194 return true ;
172- else if (expr.id () == ID_sva_ranged_always)
173- return true ;
195+ }
174196 else
175197 return false ;
176198}
@@ -193,8 +215,10 @@ bool bmc_supports_property(const exprt &expr)
193215 return bmc_supports_LTL_property (expr);
194216 else if (is_CTL (expr))
195217 return bmc_supports_CTL_property (expr);
196- else
218+ else if ( is_SVA (expr))
197219 return bmc_supports_SVA_property (expr);
220+ else
221+ return false ; // unknown category
198222}
199223
200224/* ******************************************************************\
0 commit comments