mirror of
				https://github.com/Z3Prover/z3
				synced 2025-10-31 03:32:28 +00:00 
			
		
		
		
	Add finite set API functions to access term constructors from finite_set_decl_plugin.h (#7996)
* Initial plan * Add C API for finite sets Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> * Add Python bindings for finite sets Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> * Add C++ bindings for finite sets Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> * Add documentation for finite set API Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									4c67a7271e
								
							
						
					
					
						commit
						541a554ecd
					
				
					 8 changed files with 700 additions and 1 deletions
				
			
		
							
								
								
									
										154
									
								
								FINITE_SET_API.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								FINITE_SET_API.md
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,154 @@ | ||||||
|  | # Finite Set API Documentation | ||||||
|  | 
 | ||||||
|  | This document describes the finite set API added to Z3. | ||||||
|  | 
 | ||||||
|  | ## Overview | ||||||
|  | 
 | ||||||
|  | The finite set API provides term constructors for finite sets as defined in `finite_set_decl_plugin.h`.  | ||||||
|  | These are distinct from the existing array-based sets and provide a more direct representation for finite sets. | ||||||
|  | 
 | ||||||
|  | ## C API | ||||||
|  | 
 | ||||||
|  | All functions are declared in `src/api/z3_api.h` and implemented in `src/api/api_finite_set.cpp`. | ||||||
|  | 
 | ||||||
|  | ### Sort Constructor | ||||||
|  | 
 | ||||||
|  | - `Z3_sort Z3_mk_finite_set_sort(Z3_context c, Z3_sort elem_sort)` - Create a finite set sort over element sort | ||||||
|  | 
 | ||||||
|  | ### Sort Queries | ||||||
|  | 
 | ||||||
|  | - `bool Z3_is_finite_set_sort(Z3_context c, Z3_sort s)` - Check if a sort is a finite set sort | ||||||
|  | - `Z3_sort Z3_get_finite_set_sort_basis(Z3_context c, Z3_sort s)` - Get the element sort of a finite set sort | ||||||
|  | 
 | ||||||
|  | ### Term Constructors | ||||||
|  | 
 | ||||||
|  | - `Z3_ast Z3_mk_finite_set_empty(Z3_context c, Z3_sort set_sort)` - Create an empty finite set | ||||||
|  | - `Z3_ast Z3_mk_finite_set_singleton(Z3_context c, Z3_ast elem)` - Create a singleton set | ||||||
|  | - `Z3_ast Z3_mk_finite_set_union(Z3_context c, Z3_ast s1, Z3_ast s2)` - Create the union of two sets | ||||||
|  | - `Z3_ast Z3_mk_finite_set_intersect(Z3_context c, Z3_ast s1, Z3_ast s2)` - Create the intersection | ||||||
|  | - `Z3_ast Z3_mk_finite_set_difference(Z3_context c, Z3_ast s1, Z3_ast s2)` - Create the set difference | ||||||
|  | - `Z3_ast Z3_mk_finite_set_member(Z3_context c, Z3_ast elem, Z3_ast set)` - Check membership | ||||||
|  | - `Z3_ast Z3_mk_finite_set_size(Z3_context c, Z3_ast set)` - Get the cardinality | ||||||
|  | - `Z3_ast Z3_mk_finite_set_subset(Z3_context c, Z3_ast s1, Z3_ast s2)` - Check subset relation | ||||||
|  | - `Z3_ast Z3_mk_finite_set_map(Z3_context c, Z3_ast f, Z3_ast set)` - Apply function to all elements | ||||||
|  | - `Z3_ast Z3_mk_finite_set_filter(Z3_context c, Z3_ast f, Z3_ast set)` - Filter set with predicate | ||||||
|  | - `Z3_ast Z3_mk_finite_set_range(Z3_context c, Z3_ast low, Z3_ast high)` - Create range [low, high) | ||||||
|  | 
 | ||||||
|  | ## Python API | ||||||
|  | 
 | ||||||
|  | All functions are available in `z3.py`: | ||||||
|  | 
 | ||||||
|  | ### Classes | ||||||
|  | 
 | ||||||
|  | - `FiniteSetSortRef` - Finite set sort reference | ||||||
|  | - `FiniteSetRef` - Finite set expression reference | ||||||
|  | 
 | ||||||
|  | ### Functions | ||||||
|  | 
 | ||||||
|  | - `FiniteSetSort(elem_sort)` - Create finite set sort | ||||||
|  | - `FiniteSetEmpty(set_sort)` - Create empty set | ||||||
|  | - `FiniteSetSingleton(elem)` - Create singleton set | ||||||
|  | - `FiniteSetUnion(s1, s2)` - Union (also `s1 | s2`) | ||||||
|  | - `FiniteSetIntersect(s1, s2)` - Intersection (also `s1 & s2`) | ||||||
|  | - `FiniteSetDifference(s1, s2)` - Difference (also `s1 - s2`) | ||||||
|  | - `FiniteSetMember(elem, set)` - Membership test | ||||||
|  | - `FiniteSetSize(set)` - Cardinality | ||||||
|  | - `FiniteSetSubset(s1, s2)` - Subset test | ||||||
|  | - `FiniteSetMap(f, set)` - Map function over set | ||||||
|  | - `FiniteSetFilter(f, set)` - Filter set | ||||||
|  | - `FiniteSetRange(low, high)` - Create range | ||||||
|  | - `is_finite_set(expr)` - Check if expression is a finite set | ||||||
|  | - `is_finite_set_sort(sort)` - Check if sort is a finite set sort | ||||||
|  | 
 | ||||||
|  | ### Example | ||||||
|  | 
 | ||||||
|  | ```python | ||||||
|  | from z3 import * | ||||||
|  | 
 | ||||||
|  | # Create a finite set sort over integers | ||||||
|  | int_set = FiniteSetSort(IntSort()) | ||||||
|  | 
 | ||||||
|  | # Create sets | ||||||
|  | a = Const('a', int_set) | ||||||
|  | b = Const('b', int_set) | ||||||
|  | s1 = FiniteSetSingleton(IntVal(1)) | ||||||
|  | 
 | ||||||
|  | # Use operators | ||||||
|  | union = a | b | ||||||
|  | intersect = a & b | ||||||
|  | diff = a - b | ||||||
|  | 
 | ||||||
|  | # Use with solver | ||||||
|  | solver = Solver() | ||||||
|  | solver.add(FiniteSetSize(a) == 2) | ||||||
|  | solver.add(FiniteSetMember(IntVal(1), a)) | ||||||
|  | print(solver.check()) | ||||||
|  | print(solver.model()) | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## C++ API | ||||||
|  | 
 | ||||||
|  | All functions are declared and implemented inline in `src/api/c++/z3++.h`: | ||||||
|  | 
 | ||||||
|  | ### Context Methods | ||||||
|  | 
 | ||||||
|  | - `sort context::finite_set_sort(sort& s)` - Create finite set sort | ||||||
|  | 
 | ||||||
|  | ### Free Functions | ||||||
|  | 
 | ||||||
|  | - `expr finite_set_empty(sort const& s)` - Create empty set | ||||||
|  | - `expr finite_set_singleton(expr const& e)` - Create singleton | ||||||
|  | - `expr finite_set_union(expr const& a, expr const& b)` - Union | ||||||
|  | - `expr finite_set_intersect(expr const& a, expr const& b)` - Intersection | ||||||
|  | - `expr finite_set_difference(expr const& a, expr const& b)` - Difference | ||||||
|  | - `expr finite_set_member(expr const& e, expr const& s)` - Membership | ||||||
|  | - `expr finite_set_size(expr const& s)` - Size | ||||||
|  | - `expr finite_set_subset(expr const& a, expr const& b)` - Subset | ||||||
|  | - `expr finite_set_map(expr const& f, expr const& s)` - Map | ||||||
|  | - `expr finite_set_filter(expr const& f, expr const& s)` - Filter | ||||||
|  | - `expr finite_set_range(expr const& low, expr const& high)` - Range | ||||||
|  | 
 | ||||||
|  | ### Example | ||||||
|  | 
 | ||||||
|  | ```cpp | ||||||
|  | #include <z3++.h> | ||||||
|  | 
 | ||||||
|  | z3::context c; | ||||||
|  | z3::sort int_sort = c.int_sort(); | ||||||
|  | z3::sort fs_sort = c.finite_set_sort(int_sort); | ||||||
|  | 
 | ||||||
|  | z3::expr a = c.constant("a", fs_sort); | ||||||
|  | z3::expr b = c.constant("b", fs_sort); | ||||||
|  | z3::expr union_ab = finite_set_union(a, b); | ||||||
|  | 
 | ||||||
|  | z3::solver s(c); | ||||||
|  | s.add(finite_set_size(a) == 2); | ||||||
|  | std::cout << s.check() << std::endl; | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Other Language Bindings | ||||||
|  | 
 | ||||||
|  | The C#, Java, JavaScript, OCaml, and Julia bindings are auto-generated from the C API through  | ||||||
|  | the `scripts/update_api.py` script during the build process. The `def_API` macros in `z3_api.h` | ||||||
|  | provide the metadata needed for auto-generation. | ||||||
|  | 
 | ||||||
|  | ## Implementation Details | ||||||
|  | 
 | ||||||
|  | - The finite set plugin is registered in `src/ast/reg_decl_plugins.cpp` | ||||||
|  | - The `finite_set_util` is added to the API context in `src/api/api_context.h` | ||||||
|  | - Core implementation is in `src/ast/finite_set_decl_plugin.h/cpp` | ||||||
|  | 
 | ||||||
|  | ## SMT-LIB2 Syntax | ||||||
|  | 
 | ||||||
|  | The finite set operations map to SMT-LIB2 symbols: | ||||||
|  | - `set.empty` - empty set | ||||||
|  | - `set.singleton` - singleton set | ||||||
|  | - `set.union` - union | ||||||
|  | - `set.intersect` - intersection | ||||||
|  | - `set.difference` - difference | ||||||
|  | - `set.in` - membership | ||||||
|  | - `set.size` - cardinality | ||||||
|  | - `set.subset` - subset | ||||||
|  | - `set.map` - map operation | ||||||
|  | - `set.filter` - filter operation | ||||||
|  | - `set.range` - integer range | ||||||
|  | @ -44,6 +44,7 @@ z3_add_component(api | ||||||
|     api_context.cpp |     api_context.cpp | ||||||
|     api_datalog.cpp |     api_datalog.cpp | ||||||
|     api_datatype.cpp |     api_datatype.cpp | ||||||
|  |     api_finite_set.cpp | ||||||
|     api_fpa.cpp |     api_fpa.cpp | ||||||
|     api_goal.cpp |     api_goal.cpp | ||||||
|     api_log.cpp |     api_log.cpp | ||||||
|  |  | ||||||
|  | @ -133,6 +133,7 @@ namespace api { | ||||||
|         m_fpa_util(m()), |         m_fpa_util(m()), | ||||||
|         m_sutil(m()), |         m_sutil(m()), | ||||||
|         m_recfun(m()), |         m_recfun(m()), | ||||||
|  |         m_finite_set_util(m()), | ||||||
|         m_ast_trail(m()), |         m_ast_trail(m()), | ||||||
|         m_pmanager(m_limit) { |         m_pmanager(m_limit) { | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -31,6 +31,7 @@ Revision History: | ||||||
| #include "ast/fpa_decl_plugin.h" | #include "ast/fpa_decl_plugin.h" | ||||||
| #include "ast/recfun_decl_plugin.h" | #include "ast/recfun_decl_plugin.h" | ||||||
| #include "ast/special_relations_decl_plugin.h" | #include "ast/special_relations_decl_plugin.h" | ||||||
|  | #include "ast/finite_set_decl_plugin.h" | ||||||
| #include "ast/rewriter/seq_rewriter.h" | #include "ast/rewriter/seq_rewriter.h" | ||||||
| #include "params/smt_params.h" | #include "params/smt_params.h" | ||||||
| #include "smt/smt_kernel.h" | #include "smt/smt_kernel.h" | ||||||
|  | @ -77,6 +78,7 @@ namespace api { | ||||||
|         fpa_util                   m_fpa_util; |         fpa_util                   m_fpa_util; | ||||||
|         seq_util                   m_sutil; |         seq_util                   m_sutil; | ||||||
|         recfun::util               m_recfun; |         recfun::util               m_recfun; | ||||||
|  |         finite_set_util            m_finite_set_util; | ||||||
| 
 | 
 | ||||||
|         // Support for old solver API
 |         // Support for old solver API
 | ||||||
|         smt_params                 m_fparams; |         smt_params                 m_fparams; | ||||||
|  | @ -146,6 +148,7 @@ namespace api { | ||||||
|         datatype_util& dtutil() { return m_dt_plugin->u(); } |         datatype_util& dtutil() { return m_dt_plugin->u(); } | ||||||
|         seq_util& sutil() { return m_sutil; } |         seq_util& sutil() { return m_sutil; } | ||||||
|         recfun::util& recfun() { return m_recfun; } |         recfun::util& recfun() { return m_recfun; } | ||||||
|  |         finite_set_util& fsutil() { return m_finite_set_util; } | ||||||
|         family_id get_basic_fid() const { return basic_family_id; } |         family_id get_basic_fid() const { return basic_family_id; } | ||||||
|         family_id get_array_fid() const { return m_array_fid; } |         family_id get_array_fid() const { return m_array_fid; } | ||||||
|         family_id get_arith_fid() const { return arith_family_id; } |         family_id get_arith_fid() const { return arith_family_id; } | ||||||
|  |  | ||||||
							
								
								
									
										169
									
								
								src/api/api_finite_set.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								src/api/api_finite_set.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,169 @@ | ||||||
|  | /*++
 | ||||||
|  | Copyright (c) 2025 Microsoft Corporation | ||||||
|  | 
 | ||||||
|  | Module Name: | ||||||
|  | 
 | ||||||
|  |     api_finite_set.cpp | ||||||
|  | 
 | ||||||
|  | Abstract: | ||||||
|  | 
 | ||||||
|  |     API for finite sets. | ||||||
|  | 
 | ||||||
|  | Author: | ||||||
|  | 
 | ||||||
|  |     Copilot 2025-01-21 | ||||||
|  | 
 | ||||||
|  | Revision History: | ||||||
|  | 
 | ||||||
|  | --*/ | ||||||
|  | #include "api/z3.h" | ||||||
|  | #include "api/api_log_macros.h" | ||||||
|  | #include "api/api_context.h" | ||||||
|  | #include "api/api_util.h" | ||||||
|  | #include "ast/ast_pp.h" | ||||||
|  | 
 | ||||||
|  | extern "C" { | ||||||
|  | 
 | ||||||
|  |     Z3_sort Z3_API Z3_mk_finite_set_sort(Z3_context c, Z3_sort elem_sort) { | ||||||
|  |         Z3_TRY; | ||||||
|  |         LOG_Z3_mk_finite_set_sort(c, elem_sort); | ||||||
|  |         RESET_ERROR_CODE(); | ||||||
|  |         parameter param(to_sort(elem_sort)); | ||||||
|  |         sort* ty = mk_c(c)->m().mk_sort(mk_c(c)->fsutil().get_family_id(), FINITE_SET_SORT, 1, ¶m); | ||||||
|  |         mk_c(c)->save_ast_trail(ty); | ||||||
|  |         RETURN_Z3(of_sort(ty)); | ||||||
|  |         Z3_CATCH_RETURN(nullptr); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool Z3_API Z3_is_finite_set_sort(Z3_context c, Z3_sort s) { | ||||||
|  |         Z3_TRY; | ||||||
|  |         LOG_Z3_is_finite_set_sort(c, s); | ||||||
|  |         RESET_ERROR_CODE(); | ||||||
|  |         return mk_c(c)->fsutil().is_finite_set(to_sort(s)); | ||||||
|  |         Z3_CATCH_RETURN(false); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Z3_sort Z3_API Z3_get_finite_set_sort_basis(Z3_context c, Z3_sort s) { | ||||||
|  |         Z3_TRY; | ||||||
|  |         LOG_Z3_get_finite_set_sort_basis(c, s); | ||||||
|  |         RESET_ERROR_CODE(); | ||||||
|  |         sort* elem_sort = nullptr; | ||||||
|  |         if (!mk_c(c)->fsutil().is_finite_set(to_sort(s), elem_sort)) { | ||||||
|  |             SET_ERROR_CODE(Z3_INVALID_ARG, "expected finite set sort"); | ||||||
|  |             RETURN_Z3(nullptr); | ||||||
|  |         } | ||||||
|  |         RETURN_Z3(of_sort(elem_sort)); | ||||||
|  |         Z3_CATCH_RETURN(nullptr); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Z3_ast Z3_API Z3_mk_finite_set_empty(Z3_context c, Z3_sort set_sort) { | ||||||
|  |         Z3_TRY; | ||||||
|  |         LOG_Z3_mk_finite_set_empty(c, set_sort); | ||||||
|  |         RESET_ERROR_CODE(); | ||||||
|  |         app* a = mk_c(c)->fsutil().mk_empty(to_sort(set_sort)); | ||||||
|  |         mk_c(c)->save_ast_trail(a); | ||||||
|  |         RETURN_Z3(of_ast(a)); | ||||||
|  |         Z3_CATCH_RETURN(nullptr); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Z3_ast Z3_API Z3_mk_finite_set_singleton(Z3_context c, Z3_ast elem) { | ||||||
|  |         Z3_TRY; | ||||||
|  |         LOG_Z3_mk_finite_set_singleton(c, elem); | ||||||
|  |         RESET_ERROR_CODE(); | ||||||
|  |         app* a = mk_c(c)->fsutil().mk_singleton(to_expr(elem)); | ||||||
|  |         mk_c(c)->save_ast_trail(a); | ||||||
|  |         RETURN_Z3(of_ast(a)); | ||||||
|  |         Z3_CATCH_RETURN(nullptr); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Z3_ast Z3_API Z3_mk_finite_set_union(Z3_context c, Z3_ast s1, Z3_ast s2) { | ||||||
|  |         Z3_TRY; | ||||||
|  |         LOG_Z3_mk_finite_set_union(c, s1, s2); | ||||||
|  |         RESET_ERROR_CODE(); | ||||||
|  |         app* a = mk_c(c)->fsutil().mk_union(to_expr(s1), to_expr(s2)); | ||||||
|  |         mk_c(c)->save_ast_trail(a); | ||||||
|  |         RETURN_Z3(of_ast(a)); | ||||||
|  |         Z3_CATCH_RETURN(nullptr); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Z3_ast Z3_API Z3_mk_finite_set_intersect(Z3_context c, Z3_ast s1, Z3_ast s2) { | ||||||
|  |         Z3_TRY; | ||||||
|  |         LOG_Z3_mk_finite_set_intersect(c, s1, s2); | ||||||
|  |         RESET_ERROR_CODE(); | ||||||
|  |         app* a = mk_c(c)->fsutil().mk_intersect(to_expr(s1), to_expr(s2)); | ||||||
|  |         mk_c(c)->save_ast_trail(a); | ||||||
|  |         RETURN_Z3(of_ast(a)); | ||||||
|  |         Z3_CATCH_RETURN(nullptr); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Z3_ast Z3_API Z3_mk_finite_set_difference(Z3_context c, Z3_ast s1, Z3_ast s2) { | ||||||
|  |         Z3_TRY; | ||||||
|  |         LOG_Z3_mk_finite_set_difference(c, s1, s2); | ||||||
|  |         RESET_ERROR_CODE(); | ||||||
|  |         app* a = mk_c(c)->fsutil().mk_difference(to_expr(s1), to_expr(s2)); | ||||||
|  |         mk_c(c)->save_ast_trail(a); | ||||||
|  |         RETURN_Z3(of_ast(a)); | ||||||
|  |         Z3_CATCH_RETURN(nullptr); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Z3_ast Z3_API Z3_mk_finite_set_member(Z3_context c, Z3_ast elem, Z3_ast set) { | ||||||
|  |         Z3_TRY; | ||||||
|  |         LOG_Z3_mk_finite_set_member(c, elem, set); | ||||||
|  |         RESET_ERROR_CODE(); | ||||||
|  |         app* a = mk_c(c)->fsutil().mk_in(to_expr(elem), to_expr(set)); | ||||||
|  |         mk_c(c)->save_ast_trail(a); | ||||||
|  |         RETURN_Z3(of_ast(a)); | ||||||
|  |         Z3_CATCH_RETURN(nullptr); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Z3_ast Z3_API Z3_mk_finite_set_size(Z3_context c, Z3_ast set) { | ||||||
|  |         Z3_TRY; | ||||||
|  |         LOG_Z3_mk_finite_set_size(c, set); | ||||||
|  |         RESET_ERROR_CODE(); | ||||||
|  |         app* a = mk_c(c)->fsutil().mk_size(to_expr(set)); | ||||||
|  |         mk_c(c)->save_ast_trail(a); | ||||||
|  |         RETURN_Z3(of_ast(a)); | ||||||
|  |         Z3_CATCH_RETURN(nullptr); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Z3_ast Z3_API Z3_mk_finite_set_subset(Z3_context c, Z3_ast s1, Z3_ast s2) { | ||||||
|  |         Z3_TRY; | ||||||
|  |         LOG_Z3_mk_finite_set_subset(c, s1, s2); | ||||||
|  |         RESET_ERROR_CODE(); | ||||||
|  |         app* a = mk_c(c)->fsutil().mk_subset(to_expr(s1), to_expr(s2)); | ||||||
|  |         mk_c(c)->save_ast_trail(a); | ||||||
|  |         RETURN_Z3(of_ast(a)); | ||||||
|  |         Z3_CATCH_RETURN(nullptr); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Z3_ast Z3_API Z3_mk_finite_set_map(Z3_context c, Z3_ast f, Z3_ast set) { | ||||||
|  |         Z3_TRY; | ||||||
|  |         LOG_Z3_mk_finite_set_map(c, f, set); | ||||||
|  |         RESET_ERROR_CODE(); | ||||||
|  |         app* a = mk_c(c)->fsutil().mk_map(to_expr(f), to_expr(set)); | ||||||
|  |         mk_c(c)->save_ast_trail(a); | ||||||
|  |         RETURN_Z3(of_ast(a)); | ||||||
|  |         Z3_CATCH_RETURN(nullptr); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Z3_ast Z3_API Z3_mk_finite_set_filter(Z3_context c, Z3_ast f, Z3_ast set) { | ||||||
|  |         Z3_TRY; | ||||||
|  |         LOG_Z3_mk_finite_set_filter(c, f, set); | ||||||
|  |         RESET_ERROR_CODE(); | ||||||
|  |         app* a = mk_c(c)->fsutil().mk_filter(to_expr(f), to_expr(set)); | ||||||
|  |         mk_c(c)->save_ast_trail(a); | ||||||
|  |         RETURN_Z3(of_ast(a)); | ||||||
|  |         Z3_CATCH_RETURN(nullptr); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Z3_ast Z3_API Z3_mk_finite_set_range(Z3_context c, Z3_ast low, Z3_ast high) { | ||||||
|  |         Z3_TRY; | ||||||
|  |         LOG_Z3_mk_finite_set_range(c, low, high); | ||||||
|  |         RESET_ERROR_CODE(); | ||||||
|  |         app* a = mk_c(c)->fsutil().mk_range(to_expr(low), to_expr(high)); | ||||||
|  |         mk_c(c)->save_ast_trail(a); | ||||||
|  |         RETURN_Z3(of_ast(a)); | ||||||
|  |         Z3_CATCH_RETURN(nullptr); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | }; | ||||||
|  | @ -274,6 +274,10 @@ namespace z3 { | ||||||
|            \brief Return a regular expression sort over sequences \c seq_sort. |            \brief Return a regular expression sort over sequences \c seq_sort. | ||||||
|          */ |          */ | ||||||
|         sort re_sort(sort& seq_sort); |         sort re_sort(sort& seq_sort); | ||||||
|  |         /**
 | ||||||
|  |            \brief Return a finite set sort over element sort \c s. | ||||||
|  |          */ | ||||||
|  |         sort finite_set_sort(sort& s); | ||||||
|         /**
 |         /**
 | ||||||
|            \brief Return an array sort for arrays from \c d to \c r. |            \brief Return an array sort for arrays from \c d to \c r. | ||||||
| 
 | 
 | ||||||
|  | @ -3494,6 +3498,7 @@ namespace z3 { | ||||||
|     inline sort context::char_sort() { Z3_sort s = Z3_mk_char_sort(m_ctx); check_error(); return sort(*this, s); } |     inline sort context::char_sort() { Z3_sort s = Z3_mk_char_sort(m_ctx); check_error(); return sort(*this, s); } | ||||||
|     inline sort context::seq_sort(sort& s) { Z3_sort r = Z3_mk_seq_sort(m_ctx, s); check_error(); return sort(*this, r); } |     inline sort context::seq_sort(sort& s) { Z3_sort r = Z3_mk_seq_sort(m_ctx, s); check_error(); return sort(*this, r); } | ||||||
|     inline sort context::re_sort(sort& s) { Z3_sort r = Z3_mk_re_sort(m_ctx, s); check_error(); return sort(*this, r); } |     inline sort context::re_sort(sort& s) { Z3_sort r = Z3_mk_re_sort(m_ctx, s); check_error(); return sort(*this, r); } | ||||||
|  |     inline sort context::finite_set_sort(sort& s) { Z3_sort r = Z3_mk_finite_set_sort(m_ctx, s); check_error(); return sort(*this, r); } | ||||||
|     inline sort context::fpa_sort(unsigned ebits, unsigned sbits) { Z3_sort s = Z3_mk_fpa_sort(m_ctx, ebits, sbits); check_error(); return sort(*this, s); } |     inline sort context::fpa_sort(unsigned ebits, unsigned sbits) { Z3_sort s = Z3_mk_fpa_sort(m_ctx, ebits, sbits); check_error(); return sort(*this, s); } | ||||||
| 
 | 
 | ||||||
|     template<> |     template<> | ||||||
|  | @ -4065,6 +4070,54 @@ namespace z3 { | ||||||
|         MK_EXPR2(Z3_mk_set_subset, a, b); |         MK_EXPR2(Z3_mk_set_subset, a, b); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     // finite set operations
 | ||||||
|  | 
 | ||||||
|  |     inline expr finite_set_empty(sort const& s) { | ||||||
|  |         Z3_ast r = Z3_mk_finite_set_empty(s.ctx(), s); | ||||||
|  |         s.check_error(); | ||||||
|  |         return expr(s.ctx(), r); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     inline expr finite_set_singleton(expr const& e) { | ||||||
|  |         MK_EXPR1(Z3_mk_finite_set_singleton, e); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     inline expr finite_set_union(expr const& a, expr const& b) { | ||||||
|  |         MK_EXPR2(Z3_mk_finite_set_union, a, b); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     inline expr finite_set_intersect(expr const& a, expr const& b) { | ||||||
|  |         MK_EXPR2(Z3_mk_finite_set_intersect, a, b); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     inline expr finite_set_difference(expr const& a, expr const& b) { | ||||||
|  |         MK_EXPR2(Z3_mk_finite_set_difference, a, b); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     inline expr finite_set_member(expr const& e, expr const& s) { | ||||||
|  |         MK_EXPR2(Z3_mk_finite_set_member, e, s); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     inline expr finite_set_size(expr const& s) { | ||||||
|  |         MK_EXPR1(Z3_mk_finite_set_size, s); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     inline expr finite_set_subset(expr const& a, expr const& b) { | ||||||
|  |         MK_EXPR2(Z3_mk_finite_set_subset, a, b); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     inline expr finite_set_map(expr const& f, expr const& s) { | ||||||
|  |         MK_EXPR2(Z3_mk_finite_set_map, f, s); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     inline expr finite_set_filter(expr const& f, expr const& s) { | ||||||
|  |         MK_EXPR2(Z3_mk_finite_set_filter, f, s); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     inline expr finite_set_range(expr const& low, expr const& high) { | ||||||
|  |         MK_EXPR2(Z3_mk_finite_set_range, low, high); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     // sequence and regular expression operations.
 |     // sequence and regular expression operations.
 | ||||||
|     // union is +
 |     // union is +
 | ||||||
|     // concat is overloaded to handle sequences and regular expressions
 |     // concat is overloaded to handle sequences and regular expressions
 | ||||||
|  |  | ||||||
|  | @ -678,6 +678,8 @@ def is_sort(s : Any) -> bool: | ||||||
| def _to_sort_ref(s, ctx): | def _to_sort_ref(s, ctx): | ||||||
|     if z3_debug(): |     if z3_debug(): | ||||||
|         _z3_assert(isinstance(s, Sort), "Z3 Sort expected") |         _z3_assert(isinstance(s, Sort), "Z3 Sort expected") | ||||||
|  |     if Z3_is_finite_set_sort(ctx.ref(), s): | ||||||
|  |         return FiniteSetSortRef(s, ctx) | ||||||
|     k = _sort_kind(ctx, s) |     k = _sort_kind(ctx, s) | ||||||
|     if k == Z3_BOOL_SORT: |     if k == Z3_BOOL_SORT: | ||||||
|         return BoolSortRef(s, ctx) |         return BoolSortRef(s, ctx) | ||||||
|  | @ -1184,7 +1186,11 @@ def _to_expr_ref(a, ctx): | ||||||
|     k = Z3_get_ast_kind(ctx_ref, a) |     k = Z3_get_ast_kind(ctx_ref, a) | ||||||
|     if k == Z3_QUANTIFIER_AST: |     if k == Z3_QUANTIFIER_AST: | ||||||
|         return QuantifierRef(a, ctx) |         return QuantifierRef(a, ctx) | ||||||
|     sk = Z3_get_sort_kind(ctx_ref, Z3_get_sort(ctx_ref, a)) |     # Check for finite set sort before checking sort kind | ||||||
|  |     s = Z3_get_sort(ctx_ref, a) | ||||||
|  |     if Z3_is_finite_set_sort(ctx_ref, s): | ||||||
|  |         return FiniteSetRef(a, ctx) | ||||||
|  |     sk = Z3_get_sort_kind(ctx_ref, s) | ||||||
|     if sk == Z3_BOOL_SORT: |     if sk == Z3_BOOL_SORT: | ||||||
|         return BoolRef(a, ctx) |         return BoolRef(a, ctx) | ||||||
|     if sk == Z3_INT_SORT: |     if sk == Z3_INT_SORT: | ||||||
|  | @ -5147,6 +5153,217 @@ def IsSubset(a, b): | ||||||
|     return BoolRef(Z3_mk_set_subset(ctx.ref(), a.as_ast(), b.as_ast()), ctx) |     return BoolRef(Z3_mk_set_subset(ctx.ref(), a.as_ast(), b.as_ast()), ctx) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | ######################################### | ||||||
|  | # | ||||||
|  | # Finite Sets | ||||||
|  | # | ||||||
|  | ######################################### | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class FiniteSetSortRef(SortRef): | ||||||
|  |     """Finite set sort.""" | ||||||
|  | 
 | ||||||
|  |     def element_sort(self): | ||||||
|  |         """Return the element sort of this finite set sort.""" | ||||||
|  |         return _to_sort_ref(Z3_get_finite_set_sort_basis(self.ctx_ref(), self.ast), self.ctx) | ||||||
|  | 
 | ||||||
|  |     def cast(self, val): | ||||||
|  |         """Try to cast val as a finite set expression.""" | ||||||
|  |         if is_expr(val): | ||||||
|  |             if self.eq(val.sort()): | ||||||
|  |                 return val | ||||||
|  |             else: | ||||||
|  |                 _z3_assert(False, "Cannot cast to finite set sort") | ||||||
|  |         if isinstance(val, set): | ||||||
|  |             elem_sort = self.element_sort() | ||||||
|  |             result = FiniteSetEmpty(self) | ||||||
|  |             for e in val: | ||||||
|  |                 result = FiniteSetUnion(result, FiniteSetSingleton(_py2expr(e, self.ctx, elem_sort))) | ||||||
|  |             return result | ||||||
|  |         _z3_assert(False, "Cannot cast to finite set sort") | ||||||
|  | 
 | ||||||
|  |     def subsort(self, other): | ||||||
|  |         return False | ||||||
|  | 
 | ||||||
|  |     def is_int(self): | ||||||
|  |         return False | ||||||
|  | 
 | ||||||
|  |     def is_bool(self): | ||||||
|  |         return False | ||||||
|  | 
 | ||||||
|  |     def is_datatype(self): | ||||||
|  |         return False | ||||||
|  | 
 | ||||||
|  |     def is_array(self): | ||||||
|  |         return False | ||||||
|  | 
 | ||||||
|  |     def is_bv(self): | ||||||
|  |         return False | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def is_finite_set(a): | ||||||
|  |     """Return True if a is a Z3 finite set expression. | ||||||
|  |     >>> s = FiniteSetSort(IntSort()) | ||||||
|  |     >>> is_finite_set(FiniteSetEmpty(s)) | ||||||
|  |     True | ||||||
|  |     >>> is_finite_set(IntVal(1)) | ||||||
|  |     False | ||||||
|  |     """ | ||||||
|  |     return isinstance(a, FiniteSetRef) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def is_finite_set_sort(s): | ||||||
|  |     """Return True if s is a Z3 finite set sort. | ||||||
|  |     >>> is_finite_set_sort(FiniteSetSort(IntSort())) | ||||||
|  |     True | ||||||
|  |     >>> is_finite_set_sort(IntSort()) | ||||||
|  |     False | ||||||
|  |     """ | ||||||
|  |     return isinstance(s, FiniteSetSortRef) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class FiniteSetRef(ExprRef): | ||||||
|  |     """Finite set expression.""" | ||||||
|  | 
 | ||||||
|  |     def sort(self): | ||||||
|  |         return FiniteSetSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx) | ||||||
|  | 
 | ||||||
|  |     def __or__(self, other): | ||||||
|  |         """Return the union of self and other.""" | ||||||
|  |         return FiniteSetUnion(self, other) | ||||||
|  | 
 | ||||||
|  |     def __and__(self, other): | ||||||
|  |         """Return the intersection of self and other.""" | ||||||
|  |         return FiniteSetIntersect(self, other) | ||||||
|  | 
 | ||||||
|  |     def __sub__(self, other): | ||||||
|  |         """Return the set difference of self and other.""" | ||||||
|  |         return FiniteSetDifference(self, other) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def FiniteSetSort(elem_sort): | ||||||
|  |     """Create a finite set sort over element sort elem_sort. | ||||||
|  |     >>> s = FiniteSetSort(IntSort()) | ||||||
|  |     >>> s | ||||||
|  |     FiniteSet(Int) | ||||||
|  |     """ | ||||||
|  |     return FiniteSetSortRef(Z3_mk_finite_set_sort(elem_sort.ctx_ref(), elem_sort.ast), elem_sort.ctx) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def FiniteSetEmpty(set_sort): | ||||||
|  |     """Create an empty finite set of the given sort. | ||||||
|  |     >>> s = FiniteSetSort(IntSort()) | ||||||
|  |     >>> FiniteSetEmpty(s) | ||||||
|  |     set.empty | ||||||
|  |     """ | ||||||
|  |     ctx = set_sort.ctx | ||||||
|  |     return FiniteSetRef(Z3_mk_finite_set_empty(ctx.ref(), set_sort.ast), ctx) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def FiniteSetSingleton(elem): | ||||||
|  |     """Create a singleton finite set containing elem. | ||||||
|  |     >>> FiniteSetSingleton(IntVal(1)) | ||||||
|  |     set.singleton(1) | ||||||
|  |     """ | ||||||
|  |     ctx = elem.ctx | ||||||
|  |     return FiniteSetRef(Z3_mk_finite_set_singleton(ctx.ref(), elem.as_ast()), ctx) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def FiniteSetUnion(s1, s2): | ||||||
|  |     """Create the union of two finite sets. | ||||||
|  |     >>> a = Const('a', FiniteSetSort(IntSort())) | ||||||
|  |     >>> b = Const('b', FiniteSetSort(IntSort())) | ||||||
|  |     >>> FiniteSetUnion(a, b) | ||||||
|  |     set.union(a, b) | ||||||
|  |     """ | ||||||
|  |     ctx = _ctx_from_ast_arg_list([s1, s2]) | ||||||
|  |     return FiniteSetRef(Z3_mk_finite_set_union(ctx.ref(), s1.as_ast(), s2.as_ast()), ctx) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def FiniteSetIntersect(s1, s2): | ||||||
|  |     """Create the intersection of two finite sets. | ||||||
|  |     >>> a = Const('a', FiniteSetSort(IntSort())) | ||||||
|  |     >>> b = Const('b', FiniteSetSort(IntSort())) | ||||||
|  |     >>> FiniteSetIntersect(a, b) | ||||||
|  |     set.intersect(a, b) | ||||||
|  |     """ | ||||||
|  |     ctx = _ctx_from_ast_arg_list([s1, s2]) | ||||||
|  |     return FiniteSetRef(Z3_mk_finite_set_intersect(ctx.ref(), s1.as_ast(), s2.as_ast()), ctx) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def FiniteSetDifference(s1, s2): | ||||||
|  |     """Create the set difference of two finite sets. | ||||||
|  |     >>> a = Const('a', FiniteSetSort(IntSort())) | ||||||
|  |     >>> b = Const('b', FiniteSetSort(IntSort())) | ||||||
|  |     >>> FiniteSetDifference(a, b) | ||||||
|  |     set.difference(a, b) | ||||||
|  |     """ | ||||||
|  |     ctx = _ctx_from_ast_arg_list([s1, s2]) | ||||||
|  |     return FiniteSetRef(Z3_mk_finite_set_difference(ctx.ref(), s1.as_ast(), s2.as_ast()), ctx) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def FiniteSetMember(elem, set): | ||||||
|  |     """Check if elem is a member of the finite set. | ||||||
|  |     >>> a = Const('a', FiniteSetSort(IntSort())) | ||||||
|  |     >>> FiniteSetMember(IntVal(1), a) | ||||||
|  |     set.in(1, a) | ||||||
|  |     """ | ||||||
|  |     ctx = _ctx_from_ast_arg_list([elem, set]) | ||||||
|  |     return BoolRef(Z3_mk_finite_set_member(ctx.ref(), elem.as_ast(), set.as_ast()), ctx) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def FiniteSetSize(set): | ||||||
|  |     """Get the size (cardinality) of a finite set. | ||||||
|  |     >>> a = Const('a', FiniteSetSort(IntSort())) | ||||||
|  |     >>> FiniteSetSize(a) | ||||||
|  |     set.size(a) | ||||||
|  |     """ | ||||||
|  |     ctx = set.ctx | ||||||
|  |     return ArithRef(Z3_mk_finite_set_size(ctx.ref(), set.as_ast()), ctx) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def FiniteSetSubset(s1, s2): | ||||||
|  |     """Check if s1 is a subset of s2. | ||||||
|  |     >>> a = Const('a', FiniteSetSort(IntSort())) | ||||||
|  |     >>> b = Const('b', FiniteSetSort(IntSort())) | ||||||
|  |     >>> FiniteSetSubset(a, b) | ||||||
|  |     set.subset(a, b) | ||||||
|  |     """ | ||||||
|  |     ctx = _ctx_from_ast_arg_list([s1, s2]) | ||||||
|  |     return BoolRef(Z3_mk_finite_set_subset(ctx.ref(), s1.as_ast(), s2.as_ast()), ctx) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def FiniteSetMap(f, set): | ||||||
|  |     """Apply function f to all elements of the finite set. | ||||||
|  |     >>> f = Function('f', IntSort(), IntSort()) | ||||||
|  |     >>> a = Const('a', FiniteSetSort(IntSort())) | ||||||
|  |     >>> FiniteSetMap(f, a) | ||||||
|  |     set.map(f, a) | ||||||
|  |     """ | ||||||
|  |     ctx = _ctx_from_ast_arg_list([f, set]) | ||||||
|  |     return FiniteSetRef(Z3_mk_finite_set_map(ctx.ref(), f.as_ast(), set.as_ast()), ctx) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def FiniteSetFilter(f, set): | ||||||
|  |     """Filter a finite set using predicate f. | ||||||
|  |     >>> f = Function('f', IntSort(), BoolSort()) | ||||||
|  |     >>> a = Const('a', FiniteSetSort(IntSort())) | ||||||
|  |     >>> FiniteSetFilter(f, a) | ||||||
|  |     set.filter(f, a) | ||||||
|  |     """ | ||||||
|  |     ctx = _ctx_from_ast_arg_list([f, set]) | ||||||
|  |     return FiniteSetRef(Z3_mk_finite_set_filter(ctx.ref(), f.as_ast(), set.as_ast()), ctx) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def FiniteSetRange(low, high): | ||||||
|  |     """Create a finite set of integers in the range [low, high). | ||||||
|  |     >>> FiniteSetRange(IntVal(0), IntVal(5)) | ||||||
|  |     set.range(0, 5) | ||||||
|  |     """ | ||||||
|  |     ctx = _ctx_from_ast_arg_list([low, high]) | ||||||
|  |     return FiniteSetRef(Z3_mk_finite_set_range(ctx.ref(), low.as_ast(), high.as_ast()), ctx) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| ######################################### | ######################################### | ||||||
| # | # | ||||||
| # Datatypes | # Datatypes | ||||||
|  |  | ||||||
							
								
								
									
										101
									
								
								src/api/z3_api.h
									
										
									
									
									
								
							
							
						
						
									
										101
									
								
								src/api/z3_api.h
									
										
									
									
									
								
							|  | @ -3389,6 +3389,107 @@ extern "C" { | ||||||
|     Z3_ast Z3_API Z3_mk_array_ext(Z3_context c, Z3_ast arg1, Z3_ast arg2); |     Z3_ast Z3_API Z3_mk_array_ext(Z3_context c, Z3_ast arg1, Z3_ast arg2); | ||||||
|     /**@}*/ |     /**@}*/ | ||||||
| 
 | 
 | ||||||
|  |     /** @name Finite Sets */ | ||||||
|  |     /**@{*/ | ||||||
|  |     /**
 | ||||||
|  |        \brief Create a finite set sort. | ||||||
|  | 
 | ||||||
|  |        def_API('Z3_mk_finite_set_sort', SORT, (_in(CONTEXT), _in(SORT))) | ||||||
|  |     */ | ||||||
|  |     Z3_sort Z3_API Z3_mk_finite_set_sort(Z3_context c, Z3_sort elem_sort); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |        \brief Check if a sort is a finite set sort. | ||||||
|  | 
 | ||||||
|  |        def_API('Z3_is_finite_set_sort', BOOL, (_in(CONTEXT), _in(SORT))) | ||||||
|  |     */ | ||||||
|  |     bool Z3_API Z3_is_finite_set_sort(Z3_context c, Z3_sort s); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |        \brief Get the element sort of a finite set sort. | ||||||
|  | 
 | ||||||
|  |        def_API('Z3_get_finite_set_sort_basis', SORT, (_in(CONTEXT), _in(SORT))) | ||||||
|  |     */ | ||||||
|  |     Z3_sort Z3_API Z3_get_finite_set_sort_basis(Z3_context c, Z3_sort s); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |        \brief Create an empty finite set of the given sort. | ||||||
|  | 
 | ||||||
|  |        def_API('Z3_mk_finite_set_empty', AST, (_in(CONTEXT), _in(SORT))) | ||||||
|  |     */ | ||||||
|  |     Z3_ast Z3_API Z3_mk_finite_set_empty(Z3_context c, Z3_sort set_sort); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |        \brief Create a singleton finite set. | ||||||
|  | 
 | ||||||
|  |        def_API('Z3_mk_finite_set_singleton', AST, (_in(CONTEXT), _in(AST))) | ||||||
|  |     */ | ||||||
|  |     Z3_ast Z3_API Z3_mk_finite_set_singleton(Z3_context c, Z3_ast elem); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |        \brief Create the union of two finite sets. | ||||||
|  | 
 | ||||||
|  |        def_API('Z3_mk_finite_set_union', AST, (_in(CONTEXT), _in(AST), _in(AST))) | ||||||
|  |     */ | ||||||
|  |     Z3_ast Z3_API Z3_mk_finite_set_union(Z3_context c, Z3_ast s1, Z3_ast s2); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |        \brief Create the intersection of two finite sets. | ||||||
|  | 
 | ||||||
|  |        def_API('Z3_mk_finite_set_intersect', AST, (_in(CONTEXT), _in(AST), _in(AST))) | ||||||
|  |     */ | ||||||
|  |     Z3_ast Z3_API Z3_mk_finite_set_intersect(Z3_context c, Z3_ast s1, Z3_ast s2); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |        \brief Create the set difference of two finite sets. | ||||||
|  | 
 | ||||||
|  |        def_API('Z3_mk_finite_set_difference', AST, (_in(CONTEXT), _in(AST), _in(AST))) | ||||||
|  |     */ | ||||||
|  |     Z3_ast Z3_API Z3_mk_finite_set_difference(Z3_context c, Z3_ast s1, Z3_ast s2); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |        \brief Check if an element is a member of a finite set. | ||||||
|  | 
 | ||||||
|  |        def_API('Z3_mk_finite_set_member', AST, (_in(CONTEXT), _in(AST), _in(AST))) | ||||||
|  |     */ | ||||||
|  |     Z3_ast Z3_API Z3_mk_finite_set_member(Z3_context c, Z3_ast elem, Z3_ast set); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |        \brief Get the size (cardinality) of a finite set. | ||||||
|  | 
 | ||||||
|  |        def_API('Z3_mk_finite_set_size', AST, (_in(CONTEXT), _in(AST))) | ||||||
|  |     */ | ||||||
|  |     Z3_ast Z3_API Z3_mk_finite_set_size(Z3_context c, Z3_ast set); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |        \brief Check if one finite set is a subset of another. | ||||||
|  | 
 | ||||||
|  |        def_API('Z3_mk_finite_set_subset', AST, (_in(CONTEXT), _in(AST), _in(AST))) | ||||||
|  |     */ | ||||||
|  |     Z3_ast Z3_API Z3_mk_finite_set_subset(Z3_context c, Z3_ast s1, Z3_ast s2); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |        \brief Apply a function to all elements of a finite set. | ||||||
|  | 
 | ||||||
|  |        def_API('Z3_mk_finite_set_map', AST, (_in(CONTEXT), _in(AST), _in(AST))) | ||||||
|  |     */ | ||||||
|  |     Z3_ast Z3_API Z3_mk_finite_set_map(Z3_context c, Z3_ast f, Z3_ast set); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |        \brief Filter a finite set using a predicate. | ||||||
|  | 
 | ||||||
|  |        def_API('Z3_mk_finite_set_filter', AST, (_in(CONTEXT), _in(AST), _in(AST))) | ||||||
|  |     */ | ||||||
|  |     Z3_ast Z3_API Z3_mk_finite_set_filter(Z3_context c, Z3_ast f, Z3_ast set); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |        \brief Create a finite set of integers in the range [low, high). | ||||||
|  | 
 | ||||||
|  |        def_API('Z3_mk_finite_set_range', AST, (_in(CONTEXT), _in(AST), _in(AST))) | ||||||
|  |     */ | ||||||
|  |     Z3_ast Z3_API Z3_mk_finite_set_range(Z3_context c, Z3_ast low, Z3_ast high); | ||||||
|  |     /**@}*/ | ||||||
|  | 
 | ||||||
|     /** @name Numerals */ |     /** @name Numerals */ | ||||||
|     /**@{*/ |     /**@{*/ | ||||||
|     /**
 |     /**
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue