@@ -86,6 +86,8 @@ import {
86
86
CoercibleToArith ,
87
87
NonEmptySortArray ,
88
88
FuncEntry ,
89
+ SMTSetSort ,
90
+ SMTSet ,
89
91
} from './types' ;
90
92
import { allSatisfy , assert , assertExhaustive } from './utils' ;
91
93
@@ -795,6 +797,33 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
795
797
return new ArrayImpl < [ DomainSort ] , RangeSort > ( check ( Z3 . mk_const_array ( contextPtr , domain . ptr , value . ptr ) ) ) ;
796
798
} ,
797
799
} ;
800
+ const Set = {
801
+ // reference: https://z3prover.github.io/api/html/namespacez3py.html#a545f894afeb24caa1b88b7f2a324ee7e
802
+ sort < ElemSort extends AnySort < Name > > ( sort : ElemSort ) : SMTSetSort < Name , ElemSort > {
803
+ return Array . sort ( sort , Bool . sort ( ) ) ;
804
+ } ,
805
+ const < ElemSort extends AnySort < Name > > ( name : string , sort : ElemSort ) : SMTSet < Name , ElemSort > {
806
+ return new SetImpl < ElemSort > (
807
+ check ( Z3 . mk_const ( contextPtr , _toSymbol ( name ) , Array . sort ( sort , Bool . sort ( ) ) . ptr ) ) ,
808
+ ) ;
809
+ } ,
810
+ consts < ElemSort extends AnySort < Name > > ( names : string | string [ ] , sort : ElemSort ) : SMTSet < Name , ElemSort > [ ] {
811
+ if ( typeof names === 'string' ) {
812
+ names = names . split ( ' ' ) ;
813
+ }
814
+ return names . map ( name => Set . const ( name , sort ) ) ;
815
+ } ,
816
+ empty < ElemSort extends AnySort < Name > > ( sort : ElemSort ) : SMTSet < Name , ElemSort > {
817
+ return EmptySet ( sort ) ;
818
+ } ,
819
+ val < ElemSort extends AnySort < Name > > ( values : CoercibleToMap < SortToExprMap < ElemSort , Name > , Name > [ ] , sort : ElemSort ) : SMTSet < Name , ElemSort > {
820
+ var result = EmptySet ( sort ) ;
821
+ for ( const value of values ) {
822
+ result = SetAdd ( result , value ) ;
823
+ }
824
+ return result ;
825
+ }
826
+ }
798
827
799
828
////////////////
800
829
// Operations //
@@ -1249,6 +1278,49 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
1249
1278
> ;
1250
1279
}
1251
1280
1281
+ function SetUnion < ElemSort extends AnySort < Name > > ( ...args : SMTSet < Name , ElemSort > [ ] ) : SMTSet < Name , ElemSort > {
1282
+ return new SetImpl < ElemSort > ( check ( Z3 . mk_set_union ( contextPtr , args . map ( arg => arg . ast ) ) ) ) ;
1283
+ }
1284
+
1285
+ function SetIntersect < ElemSort extends AnySort < Name > > ( ...args : SMTSet < Name , ElemSort > [ ] ) : SMTSet < Name , ElemSort > {
1286
+ return new SetImpl < ElemSort > ( check ( Z3 . mk_set_intersect ( contextPtr , args . map ( arg => arg . ast ) ) ) ) ;
1287
+ }
1288
+
1289
+ function SetDifference < ElemSort extends AnySort < Name > > ( a : SMTSet < Name , ElemSort > , b : SMTSet < Name , ElemSort > ) : SMTSet < Name , ElemSort > {
1290
+ return new SetImpl < ElemSort > ( check ( Z3 . mk_set_difference ( contextPtr , a . ast , b . ast ) ) ) ;
1291
+ }
1292
+
1293
+ function SetHasSize < ElemSort extends AnySort < Name > > ( set : SMTSet < Name , ElemSort > , size : bigint | number | string | IntNum < Name > ) : Bool < Name > {
1294
+ const a = typeof size === 'object' ? Int . sort ( ) . cast ( size ) : Int . sort ( ) . cast ( size ) ;
1295
+ return new BoolImpl ( check ( Z3 . mk_set_has_size ( contextPtr , set . ast , a . ast ) ) ) ;
1296
+ }
1297
+
1298
+ function SetAdd < ElemSort extends AnySort < Name > > ( set : SMTSet < Name , ElemSort > , elem : CoercibleToMap < SortToExprMap < ElemSort , Name > , Name > ) : SMTSet < Name , ElemSort > {
1299
+ const arg = set . elemSort ( ) . cast ( elem as any ) ;
1300
+ return new SetImpl < ElemSort > ( check ( Z3 . mk_set_add ( contextPtr , set . ast , arg . ast ) ) ) ;
1301
+ }
1302
+ function SetDel < ElemSort extends AnySort < Name > > ( set : SMTSet < Name , ElemSort > , elem : CoercibleToMap < SortToExprMap < ElemSort , Name > , Name > ) : SMTSet < Name , ElemSort > {
1303
+ const arg = set . elemSort ( ) . cast ( elem as any ) ;
1304
+ return new SetImpl < ElemSort > ( check ( Z3 . mk_set_del ( contextPtr , set . ast , arg . ast ) ) ) ;
1305
+ }
1306
+ function SetComplement < ElemSort extends AnySort < Name > > ( set : SMTSet < Name , ElemSort > ) : SMTSet < Name , ElemSort > {
1307
+ return new SetImpl < ElemSort > ( check ( Z3 . mk_set_complement ( contextPtr , set . ast ) ) ) ;
1308
+ }
1309
+
1310
+ function EmptySet < ElemSort extends AnySort < Name > > ( sort : ElemSort ) : SMTSet < Name , ElemSort > {
1311
+ return new SetImpl < ElemSort > ( check ( Z3 . mk_empty_set ( contextPtr , sort . ptr ) ) ) ;
1312
+ }
1313
+ function FullSet < ElemSort extends AnySort < Name > > ( sort : ElemSort ) : SMTSet < Name , ElemSort > {
1314
+ return new SetImpl < ElemSort > ( check ( Z3 . mk_full_set ( contextPtr , sort . ptr ) ) ) ;
1315
+ }
1316
+ function isMember < ElemSort extends AnySort < Name > > ( elem : CoercibleToMap < SortToExprMap < ElemSort , Name > , Name > , set : SMTSet < Name , ElemSort > ) : Bool < Name > {
1317
+ const arg = set . elemSort ( ) . cast ( elem as any ) ;
1318
+ return new BoolImpl ( check ( Z3 . mk_set_member ( contextPtr , arg . ast , set . ast ) ) ) ;
1319
+ }
1320
+ function isSubset < ElemSort extends AnySort < Name > > ( a : SMTSet < Name , ElemSort > , b : SMTSet < Name , ElemSort > ) : Bool < Name > {
1321
+ return new BoolImpl ( check ( Z3 . mk_set_subset ( contextPtr , a . ast , b . ast ) ) ) ;
1322
+ }
1323
+
1252
1324
class AstImpl < Ptr extends Z3_ast > implements Ast < Name , Ptr > {
1253
1325
declare readonly __typename : Ast [ '__typename' ] ;
1254
1326
readonly ctx : Context < Name > ;
@@ -2536,6 +2608,41 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
2536
2608
}
2537
2609
}
2538
2610
2611
+ class SetImpl < ElemSort extends Sort < Name > > extends ExprImpl < Z3_ast , ArraySortImpl < [ ElemSort ] , BoolSort < Name > > > implements SMTSet < Name , ElemSort > {
2612
+ declare readonly __typename : 'Array' ;
2613
+
2614
+ elemSort ( ) : ElemSort {
2615
+ return this . sort . domain ( ) ;
2616
+ }
2617
+ union ( ...args : SMTSet < Name , ElemSort > [ ] ) : SMTSet < Name , ElemSort > {
2618
+ return SetUnion ( this , ...args ) ;
2619
+ }
2620
+ intersect ( ...args : SMTSet < Name , ElemSort > [ ] ) : SMTSet < Name , ElemSort > {
2621
+ return SetIntersect ( this , ...args ) ;
2622
+ }
2623
+ diff ( b : SMTSet < Name , ElemSort > ) : SMTSet < Name , ElemSort > {
2624
+ return SetDifference ( this , b ) ;
2625
+ }
2626
+ hasSize ( size : string | number | bigint | IntNum < Name > ) : Bool < Name > {
2627
+ return SetHasSize ( this , size ) ;
2628
+ }
2629
+ add ( elem : CoercibleToMap < SortToExprMap < ElemSort , Name > , Name > ) : SMTSet < Name , ElemSort > {
2630
+ return SetAdd ( this , elem ) ;
2631
+ }
2632
+ del ( elem : CoercibleToMap < SortToExprMap < ElemSort , Name > , Name > ) : SMTSet < Name , ElemSort > {
2633
+ return SetDel ( this , elem ) ;
2634
+ }
2635
+ complement ( ) : SMTSet < Name , ElemSort > {
2636
+ return SetComplement ( this ) ;
2637
+ }
2638
+ contains ( elem : CoercibleToMap < SortToExprMap < ElemSort , Name > , Name > ) : Bool < Name > {
2639
+ return isMember ( elem , this ) ;
2640
+ }
2641
+ subsetOf ( b : SMTSet < Name , ElemSort > ) : Bool < Name > {
2642
+ return isSubset ( this , b ) ;
2643
+ }
2644
+ }
2645
+
2539
2646
class QuantifierImpl <
2540
2647
QVarSorts extends NonEmptySortArray < Name > ,
2541
2648
QSort extends BoolSort < Name > | SMTArraySort < Name , QVarSorts > ,
@@ -2917,6 +3024,7 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
2917
3024
Real,
2918
3025
BitVec,
2919
3026
Array,
3027
+ Set,
2920
3028
2921
3029
////////////////
2922
3030
// Operations //
@@ -2979,6 +3087,18 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
2979
3087
// Loading //
2980
3088
/////////////
2981
3089
ast_from_string,
3090
+
3091
+ SetUnion,
3092
+ SetIntersect,
3093
+ SetDifference,
3094
+ SetHasSize,
3095
+ SetAdd,
3096
+ SetDel,
3097
+ SetComplement,
3098
+ EmptySet,
3099
+ FullSet,
3100
+ isMember,
3101
+ isSubset,
2982
3102
} ;
2983
3103
cleanup . register ( ctx , ( ) => Z3 . del_context ( contextPtr ) ) ;
2984
3104
return ctx ;
0 commit comments