@@ -65,6 +65,8 @@ class bdd_enginet
65
65
const namespacet ns;
66
66
netlistt netlist;
67
67
68
+ static bool property_supported (const exprt &);
69
+
68
70
// the Manager must appear before any BDDs
69
71
// to do the cleanup in the right order
70
72
mini_bdd_mgrt mgr;
@@ -196,10 +198,9 @@ property_checker_resultt bdd_enginet::operator()()
196
198
<< " , nodes: " << netlist.number_of_nodes ()
197
199
<< messaget::eom;
198
200
199
- const auto property_map = properties.make_property_map ();
200
-
201
- for (const auto &[_, expr] : property_map)
202
- get_atomic_propositions (expr);
201
+ for (const auto &property : properties.properties )
202
+ if (property_supported (property.normalized_expr ))
203
+ get_atomic_propositions (property.normalized_expr );
203
204
204
205
message.status () << " Building BDD for netlist" << messaget::eom;
205
206
@@ -437,6 +438,54 @@ void bdd_enginet::compute_counterexample(
437
438
438
439
/* ******************************************************************\
439
440
441
+ Function: bdd_enginet::property_supported
442
+
443
+ Inputs:
444
+
445
+ Outputs:
446
+
447
+ Purpose:
448
+
449
+ \*******************************************************************/
450
+
451
+ bool bdd_enginet::property_supported (const exprt &expr)
452
+ {
453
+ // Our engine knows all of CTL.
454
+ if (is_CTL (expr))
455
+ return true ;
456
+
457
+ if (is_LTL (expr))
458
+ {
459
+ // We can map selected path properties to CTL.
460
+ return is_Gp (expr) || is_GFp (expr);
461
+ }
462
+
463
+ if (is_SVA (expr))
464
+ {
465
+ if (
466
+ expr.id () == ID_sva_always &&
467
+ !has_temporal_operator (to_sva_always_expr (expr).op ()))
468
+ {
469
+ // always p
470
+ return true ;
471
+ }
472
+
473
+ if (
474
+ expr.id () == ID_sva_always &&
475
+ to_sva_always_expr (expr).op ().id () == ID_sva_s_eventually &&
476
+ !has_temporal_operator (
477
+ to_sva_s_eventually_expr (to_sva_always_expr (expr).op ()).op ()))
478
+ {
479
+ // always s_eventually p
480
+ return true ;
481
+ }
482
+ }
483
+
484
+ return false ;
485
+ }
486
+
487
+ /* ******************************************************************\
488
+
440
489
Function: bdd_enginet::check_property
441
490
442
491
Inputs:
@@ -455,24 +504,26 @@ void bdd_enginet::check_property(propertyt &property)
455
504
if (property.is_assumed ())
456
505
return ;
457
506
507
+ if (!property_supported (property.normalized_expr ))
508
+ {
509
+ property.failure (" property not supported by BDD engine" );
510
+ return ;
511
+ }
512
+
458
513
message.status () << " Checking " << property.name << messaget::eom;
459
514
property.status =propertyt::statust::UNKNOWN;
460
515
461
- // special treatment for AGp
462
- auto is_AGp = [](const exprt &expr) {
463
- return (expr.id () == ID_AG || expr.id () == ID_G ||
464
- expr.id () == ID_sva_always) &&
465
- !has_temporal_operator (to_unary_expr (expr).op ());
466
- };
467
-
468
516
// Our engine knows CTL only.
469
517
// We map selected path properties to CTL.
470
518
471
- if (
472
- property.normalized_expr .id () == ID_G &&
473
- to_G_expr (property.normalized_expr ).op ().id () == ID_F &&
474
- !has_temporal_operator (
475
- to_F_expr (to_G_expr (property.normalized_expr ).op ()).op ()))
519
+ if (is_Gp (property.normalized_expr ))
520
+ {
521
+ // G p --> AG p
522
+ auto p = to_G_expr (property.normalized_expr ).op ();
523
+ property.normalized_expr = AG_exprt{p};
524
+ }
525
+
526
+ if (is_GFp (property.normalized_expr ))
476
527
{
477
528
// G F p --> AG AF p
478
529
auto p = to_F_expr (to_G_expr (property.normalized_expr ).op ()).op ();
@@ -494,6 +545,15 @@ void bdd_enginet::check_property(propertyt &property)
494
545
property.normalized_expr = AG_exprt{AF_exprt{p}};
495
546
}
496
547
548
+ if (
549
+ property.normalized_expr .id () == ID_sva_always &&
550
+ !has_temporal_operator (to_sva_always_expr (property.normalized_expr ).op ()))
551
+ {
552
+ // always p --> AG p
553
+ auto p = to_sva_always_expr (property.normalized_expr ).op ();
554
+ property.normalized_expr = AG_exprt{p};
555
+ }
556
+
497
557
if (is_AGp (property.normalized_expr ))
498
558
{
499
559
check_AGp (property);
@@ -503,7 +563,7 @@ void bdd_enginet::check_property(propertyt &property)
503
563
check_CTL (property);
504
564
}
505
565
else
506
- property. failure ( " property not supported by BDD engine " );
566
+ DATA_INVARIANT ( false , " unexpected normalized property " );
507
567
}
508
568
509
569
/* ******************************************************************\
0 commit comments