@@ -1245,15 +1245,32 @@ impl<V> Atom<V> {
12451245/// While it allows arbitrary [`Atom`] in its `Atom` variant, we only expect atoms with known
12461246/// predicates (i.e., predicates other than `Pred::Var`) to appear in formulas. It is our TODO to
12471247/// enforce this restriction statically. Also see the definition of [`Body`].
1248- #[ derive( Debug , Clone ) ]
1248+ #[ derive( Clone ) ]
12491249pub enum Formula < V = TermVarIdx > {
12501250 Atom ( Atom < V > ) ,
12511251 Not ( Box < Formula < V > > ) ,
12521252 And ( Vec < Formula < V > > ) ,
12531253 Or ( Vec < Formula < V > > ) ,
1254+ Implies ( Box < Formula < V > > , Box < Formula < V > > ) ,
12541255 Exists ( Vec < ( String , Sort ) > , Box < Formula < V > > ) ,
12551256}
12561257
1258+ impl < V > std:: fmt:: Debug for Formula < V >
1259+ where
1260+ V : std:: fmt:: Debug ,
1261+ {
1262+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
1263+ match self {
1264+ Formula :: Atom ( atom) => atom. fmt ( f) ,
1265+ Formula :: Not ( fo) => f. debug_tuple ( "Not" ) . field ( fo) . finish ( ) ,
1266+ Formula :: And ( fs) => f. debug_tuple ( "And" ) . field ( fs) . finish ( ) ,
1267+ Formula :: Or ( fs) => f. debug_tuple ( "Or" ) . field ( fs) . finish ( ) ,
1268+ Formula :: Implies ( lhs, rhs) => write ! ( f, "({lhs:?} ==> {rhs:?})" ) ,
1269+ Formula :: Exists ( vars, fo) => f. debug_tuple ( "Exists" ) . field ( vars) . field ( fo) . finish ( ) ,
1270+ }
1271+ }
1272+ }
1273+
12571274impl < V > Default for Formula < V > {
12581275 fn default ( ) -> Self {
12591276 Formula :: top ( )
@@ -1293,6 +1310,13 @@ where
12931310 ) ;
12941311 inner. group ( )
12951312 }
1313+ Formula :: Implies ( lhs, rhs) => lhs
1314+ . pretty_atom ( allocator)
1315+ . append ( allocator. space ( ) )
1316+ . append ( allocator. text ( "==>" ) )
1317+ . append ( allocator. line ( ) )
1318+ . append ( rhs. pretty_atom ( allocator) )
1319+ . group ( ) ,
12961320 Formula :: Exists ( vars, fo) => {
12971321 let vars = allocator. intersperse (
12981322 vars. iter ( ) . map ( |( name, sort) | {
@@ -1327,7 +1351,7 @@ impl<V> Formula<V> {
13271351 D :: Doc : Clone ,
13281352 {
13291353 match self {
1330- Formula :: And ( _) | Formula :: Or ( _) | Formula :: Exists { .. } => {
1354+ Formula :: And ( _) | Formula :: Or ( _) | Formula :: Implies ( _ , _ ) | Formula :: Exists { .. } => {
13311355 self . pretty ( allocator) . parens ( )
13321356 }
13331357 _ => self . pretty ( allocator) ,
@@ -1348,6 +1372,7 @@ impl<V> Formula<V> {
13481372 Formula :: Not ( fo) => fo. is_bottom ( ) ,
13491373 Formula :: And ( fs) => fs. iter ( ) . all ( Formula :: is_top) ,
13501374 Formula :: Or ( fs) => fs. iter ( ) . any ( Formula :: is_top) ,
1375+ Formula :: Implies ( lhs, rhs) => lhs. is_bottom ( ) || rhs. is_top ( ) ,
13511376 Formula :: Exists ( _, fo) => fo. is_top ( ) ,
13521377 }
13531378 }
@@ -1358,6 +1383,7 @@ impl<V> Formula<V> {
13581383 Formula :: Not ( fo) => fo. is_top ( ) ,
13591384 Formula :: And ( fs) => fs. iter ( ) . any ( Formula :: is_bottom) ,
13601385 Formula :: Or ( fs) => fs. iter ( ) . all ( Formula :: is_bottom) ,
1386+ Formula :: Implies ( lhs, rhs) => lhs. is_top ( ) && rhs. is_bottom ( ) ,
13611387 Formula :: Exists ( _, fo) => fo. is_bottom ( ) ,
13621388 }
13631389 }
@@ -1389,6 +1415,10 @@ impl<V> Formula<V> {
13891415 }
13901416 }
13911417
1418+ pub fn implies ( self , other : Self ) -> Self {
1419+ Formula :: Implies ( Box :: new ( self ) , Box :: new ( other) )
1420+ }
1421+
13921422 pub fn exists ( vars : Vec < ( String , Sort ) > , body : Self ) -> Self {
13931423 Formula :: Exists ( vars, Box :: new ( body) )
13941424 }
@@ -1406,6 +1436,9 @@ impl<V> Formula<V> {
14061436 Formula :: And ( fs. into_iter ( ) . map ( |fo| fo. subst_var ( & mut f) ) . collect ( ) )
14071437 }
14081438 Formula :: Or ( fs) => Formula :: Or ( fs. into_iter ( ) . map ( |fo| fo. subst_var ( & mut f) ) . collect ( ) ) ,
1439+ Formula :: Implies ( lhs, rhs) => {
1440+ Formula :: Implies ( Box :: new ( lhs. subst_var ( & mut f) ) , Box :: new ( rhs. subst_var ( f) ) )
1441+ }
14091442 Formula :: Exists ( vars, fo) => Formula :: Exists ( vars, Box :: new ( fo. subst_var ( f) ) ) ,
14101443 }
14111444 }
@@ -1421,6 +1454,9 @@ impl<V> Formula<V> {
14211454 Formula :: Not ( fo) => Formula :: Not ( Box :: new ( fo. map_var ( & mut f) ) ) ,
14221455 Formula :: And ( fs) => Formula :: And ( fs. into_iter ( ) . map ( |fo| fo. map_var ( & mut f) ) . collect ( ) ) ,
14231456 Formula :: Or ( fs) => Formula :: Or ( fs. into_iter ( ) . map ( |fo| fo. map_var ( & mut f) ) . collect ( ) ) ,
1457+ Formula :: Implies ( lhs, rhs) => {
1458+ Formula :: Implies ( Box :: new ( lhs. map_var ( & mut f) ) , Box :: new ( rhs. map_var ( f) ) )
1459+ }
14241460 Formula :: Exists ( vars, fo) => Formula :: Exists ( vars, Box :: new ( fo. map_var ( f) ) ) ,
14251461 }
14261462 }
@@ -1435,6 +1471,7 @@ impl<V> Formula<V> {
14351471 Formula :: Not ( fo) => Box :: new ( fo. fv ( ) ) ,
14361472 Formula :: And ( fs) => Box :: new ( fs. iter ( ) . flat_map ( Formula :: fv) ) ,
14371473 Formula :: Or ( fs) => Box :: new ( fs. iter ( ) . flat_map ( Formula :: fv) ) ,
1474+ Formula :: Implies ( lhs, rhs) => Box :: new ( lhs. fv ( ) . chain ( rhs. fv ( ) ) ) ,
14381475 Formula :: Exists ( _, fo) => Box :: new ( fo. fv ( ) ) ,
14391476 }
14401477 }
@@ -1449,6 +1486,7 @@ impl<V> Formula<V> {
14491486 Formula :: Not ( fo) => Box :: new ( fo. iter_atoms ( ) ) ,
14501487 Formula :: And ( fs) => Box :: new ( fs. iter ( ) . flat_map ( Formula :: iter_atoms) ) ,
14511488 Formula :: Or ( fs) => Box :: new ( fs. iter ( ) . flat_map ( Formula :: iter_atoms) ) ,
1489+ Formula :: Implies ( lhs, rhs) => Box :: new ( lhs. iter_atoms ( ) . chain ( rhs. iter_atoms ( ) ) ) ,
14521490 Formula :: Exists ( _, fo) => Box :: new ( fo. iter_atoms ( ) ) ,
14531491 }
14541492 }
@@ -1469,6 +1507,17 @@ impl<V> Formula<V> {
14691507 match self {
14701508 Formula :: Atom ( _atom) => { }
14711509 Formula :: Not ( fo) => fo. simplify ( ) ,
1510+ Formula :: Implies ( lhs, rhs) => {
1511+ lhs. simplify ( ) ;
1512+ rhs. simplify ( ) ;
1513+ if lhs. is_bottom ( ) || rhs. is_top ( ) {
1514+ * self = Formula :: top ( ) ;
1515+ } else if lhs. is_top ( ) {
1516+ * self = std:: mem:: take ( & mut * * rhs) ;
1517+ } else if rhs. is_bottom ( ) {
1518+ * self = std:: mem:: take ( & mut * * lhs) . not ( ) ;
1519+ }
1520+ }
14721521 Formula :: And ( fs) => {
14731522 for fo in & mut * fs {
14741523 fo. simplify ( ) ;
@@ -1624,7 +1673,7 @@ where
16241673 . into_iter ( )
16251674 . map ( |a| a. guarded ( guard. clone ( ) ) )
16261675 . collect ( ) ,
1627- formula : guard. not ( ) . or ( formula) ,
1676+ formula : guard. implies ( formula) ,
16281677 }
16291678 }
16301679}
0 commit comments