@@ -1251,6 +1251,7 @@ pub enum Formula<V = TermVarIdx> {
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
@@ -1293,6 +1294,13 @@ where
12931294 ) ;
12941295 inner. group ( )
12951296 }
1297+ Formula :: Implies ( lhs, rhs) => lhs
1298+ . pretty_atom ( allocator)
1299+ . append ( allocator. space ( ) )
1300+ . append ( allocator. text ( "==>" ) )
1301+ . append ( allocator. line ( ) )
1302+ . append ( rhs. pretty_atom ( allocator) )
1303+ . group ( ) ,
12961304 Formula :: Exists ( vars, fo) => {
12971305 let vars = allocator. intersperse (
12981306 vars. iter ( ) . map ( |( name, sort) | {
@@ -1327,7 +1335,7 @@ impl<V> Formula<V> {
13271335 D :: Doc : Clone ,
13281336 {
13291337 match self {
1330- Formula :: And ( _) | Formula :: Or ( _) | Formula :: Exists { .. } => {
1338+ Formula :: And ( _) | Formula :: Or ( _) | Formula :: Implies ( _ , _ ) | Formula :: Exists { .. } => {
13311339 self . pretty ( allocator) . parens ( )
13321340 }
13331341 _ => self . pretty ( allocator) ,
@@ -1348,6 +1356,7 @@ impl<V> Formula<V> {
13481356 Formula :: Not ( fo) => fo. is_bottom ( ) ,
13491357 Formula :: And ( fs) => fs. iter ( ) . all ( Formula :: is_top) ,
13501358 Formula :: Or ( fs) => fs. iter ( ) . any ( Formula :: is_top) ,
1359+ Formula :: Implies ( lhs, rhs) => lhs. is_bottom ( ) || rhs. is_top ( ) ,
13511360 Formula :: Exists ( _, fo) => fo. is_top ( ) ,
13521361 }
13531362 }
@@ -1358,6 +1367,7 @@ impl<V> Formula<V> {
13581367 Formula :: Not ( fo) => fo. is_top ( ) ,
13591368 Formula :: And ( fs) => fs. iter ( ) . any ( Formula :: is_bottom) ,
13601369 Formula :: Or ( fs) => fs. iter ( ) . all ( Formula :: is_bottom) ,
1370+ Formula :: Implies ( lhs, rhs) => lhs. is_top ( ) && rhs. is_bottom ( ) ,
13611371 Formula :: Exists ( _, fo) => fo. is_bottom ( ) ,
13621372 }
13631373 }
@@ -1389,6 +1399,10 @@ impl<V> Formula<V> {
13891399 }
13901400 }
13911401
1402+ pub fn implies ( self , other : Self ) -> Self {
1403+ Formula :: Implies ( Box :: new ( self ) , Box :: new ( other) )
1404+ }
1405+
13921406 pub fn exists ( vars : Vec < ( String , Sort ) > , body : Self ) -> Self {
13931407 Formula :: Exists ( vars, Box :: new ( body) )
13941408 }
@@ -1406,6 +1420,9 @@ impl<V> Formula<V> {
14061420 Formula :: And ( fs. into_iter ( ) . map ( |fo| fo. subst_var ( & mut f) ) . collect ( ) )
14071421 }
14081422 Formula :: Or ( fs) => Formula :: Or ( fs. into_iter ( ) . map ( |fo| fo. subst_var ( & mut f) ) . collect ( ) ) ,
1423+ Formula :: Implies ( lhs, rhs) => {
1424+ Formula :: Implies ( Box :: new ( lhs. subst_var ( & mut f) ) , Box :: new ( rhs. subst_var ( f) ) )
1425+ }
14091426 Formula :: Exists ( vars, fo) => Formula :: Exists ( vars, Box :: new ( fo. subst_var ( f) ) ) ,
14101427 }
14111428 }
@@ -1421,6 +1438,9 @@ impl<V> Formula<V> {
14211438 Formula :: Not ( fo) => Formula :: Not ( Box :: new ( fo. map_var ( & mut f) ) ) ,
14221439 Formula :: And ( fs) => Formula :: And ( fs. into_iter ( ) . map ( |fo| fo. map_var ( & mut f) ) . collect ( ) ) ,
14231440 Formula :: Or ( fs) => Formula :: Or ( fs. into_iter ( ) . map ( |fo| fo. map_var ( & mut f) ) . collect ( ) ) ,
1441+ Formula :: Implies ( lhs, rhs) => {
1442+ Formula :: Implies ( Box :: new ( lhs. map_var ( & mut f) ) , Box :: new ( rhs. map_var ( f) ) )
1443+ }
14241444 Formula :: Exists ( vars, fo) => Formula :: Exists ( vars, Box :: new ( fo. map_var ( f) ) ) ,
14251445 }
14261446 }
@@ -1435,6 +1455,7 @@ impl<V> Formula<V> {
14351455 Formula :: Not ( fo) => Box :: new ( fo. fv ( ) ) ,
14361456 Formula :: And ( fs) => Box :: new ( fs. iter ( ) . flat_map ( Formula :: fv) ) ,
14371457 Formula :: Or ( fs) => Box :: new ( fs. iter ( ) . flat_map ( Formula :: fv) ) ,
1458+ Formula :: Implies ( lhs, rhs) => Box :: new ( lhs. fv ( ) . chain ( rhs. fv ( ) ) ) ,
14381459 Formula :: Exists ( _, fo) => Box :: new ( fo. fv ( ) ) ,
14391460 }
14401461 }
@@ -1449,6 +1470,7 @@ impl<V> Formula<V> {
14491470 Formula :: Not ( fo) => Box :: new ( fo. iter_atoms ( ) ) ,
14501471 Formula :: And ( fs) => Box :: new ( fs. iter ( ) . flat_map ( Formula :: iter_atoms) ) ,
14511472 Formula :: Or ( fs) => Box :: new ( fs. iter ( ) . flat_map ( Formula :: iter_atoms) ) ,
1473+ Formula :: Implies ( lhs, rhs) => Box :: new ( lhs. iter_atoms ( ) . chain ( rhs. iter_atoms ( ) ) ) ,
14521474 Formula :: Exists ( _, fo) => Box :: new ( fo. iter_atoms ( ) ) ,
14531475 }
14541476 }
@@ -1469,6 +1491,17 @@ impl<V> Formula<V> {
14691491 match self {
14701492 Formula :: Atom ( _atom) => { }
14711493 Formula :: Not ( fo) => fo. simplify ( ) ,
1494+ Formula :: Implies ( lhs, rhs) => {
1495+ lhs. simplify ( ) ;
1496+ rhs. simplify ( ) ;
1497+ if lhs. is_bottom ( ) || rhs. is_top ( ) {
1498+ * self = Formula :: top ( ) ;
1499+ } else if lhs. is_top ( ) {
1500+ * self = std:: mem:: take ( & mut * * rhs) ;
1501+ } else if rhs. is_bottom ( ) {
1502+ * self = std:: mem:: take ( & mut * * lhs) . not ( ) ;
1503+ }
1504+ }
14721505 Formula :: And ( fs) => {
14731506 for fo in & mut * fs {
14741507 fo. simplify ( ) ;
@@ -1624,7 +1657,7 @@ where
16241657 . into_iter ( )
16251658 . map ( |a| a. guarded ( guard. clone ( ) ) )
16261659 . collect ( ) ,
1627- formula : guard. not ( ) . or ( formula) ,
1660+ formula : guard. implies ( formula) ,
16281661 }
16291662 }
16301663}
0 commit comments