From 299bbb81a1091b0a5071882f58a57fbcc8df776b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 29 Oct 2025 23:19:28 +0000 Subject: [PATCH 1/5] Initial plan From e85eaaefc1247b1891c19d772ce4050d91e7d4f5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 29 Oct 2025 23:42:34 +0000 Subject: [PATCH 2/5] Add finite set API support for Java and C# Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> --- src/api/dotnet/Context.cs | 174 ++++++++++++++++++++++++++++++++ src/api/dotnet/FiniteSetSort.cs | 53 ++++++++++ src/api/java/Context.java | 139 +++++++++++++++++++++++++ src/api/java/FiniteSetSort.java | 42 ++++++++ 4 files changed, 408 insertions(+) create mode 100644 src/api/dotnet/FiniteSetSort.cs create mode 100644 src/api/java/FiniteSetSort.java diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index 49f183428..549b86193 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -2442,6 +2442,180 @@ namespace Microsoft.Z3 #endregion + #region Finite Sets + + /// + /// Create a finite set sort over the given element sort. + /// + public FiniteSetSort MkFiniteSetSort(Sort elemSort) + { + Debug.Assert(elemSort != null); + + CheckContextMatch(elemSort); + return new FiniteSetSort(this, elemSort); + } + + /// + /// Check if a sort is a finite set sort. + /// + public bool IsFiniteSetSort(Sort s) + { + Debug.Assert(s != null); + + CheckContextMatch(s); + return Native.Z3_is_finite_set_sort(nCtx, s.NativeObject) != 0; + } + + /// + /// Get the element sort (basis) of a finite set sort. + /// + public Sort GetFiniteSetSortBasis(Sort s) + { + Debug.Assert(s != null); + + CheckContextMatch(s); + return Sort.Create(this, Native.Z3_get_finite_set_sort_basis(nCtx, s.NativeObject)); + } + + /// + /// Create an empty finite set. + /// + public Expr MkFiniteSetEmpty(Sort setSort) + { + Debug.Assert(setSort != null); + + CheckContextMatch(setSort); + return Expr.Create(this, Native.Z3_mk_finite_set_empty(nCtx, setSort.NativeObject)); + } + + /// + /// Create a singleton finite set. + /// + public Expr MkFiniteSetSingleton(Expr elem) + { + Debug.Assert(elem != null); + + CheckContextMatch(elem); + return Expr.Create(this, Native.Z3_mk_finite_set_singleton(nCtx, elem.NativeObject)); + } + + /// + /// Create the union of two finite sets. + /// + public Expr MkFiniteSetUnion(Expr s1, Expr s2) + { + Debug.Assert(s1 != null); + Debug.Assert(s2 != null); + + CheckContextMatch(s1); + CheckContextMatch(s2); + return Expr.Create(this, Native.Z3_mk_finite_set_union(nCtx, s1.NativeObject, s2.NativeObject)); + } + + /// + /// Create the intersection of two finite sets. + /// + public Expr MkFiniteSetIntersect(Expr s1, Expr s2) + { + Debug.Assert(s1 != null); + Debug.Assert(s2 != null); + + CheckContextMatch(s1); + CheckContextMatch(s2); + return Expr.Create(this, Native.Z3_mk_finite_set_intersect(nCtx, s1.NativeObject, s2.NativeObject)); + } + + /// + /// Create the difference of two finite sets. + /// + public Expr MkFiniteSetDifference(Expr s1, Expr s2) + { + Debug.Assert(s1 != null); + Debug.Assert(s2 != null); + + CheckContextMatch(s1); + CheckContextMatch(s2); + return Expr.Create(this, Native.Z3_mk_finite_set_difference(nCtx, s1.NativeObject, s2.NativeObject)); + } + + /// + /// Check for membership in a finite set. + /// + public BoolExpr MkFiniteSetMember(Expr elem, Expr set) + { + Debug.Assert(elem != null); + Debug.Assert(set != null); + + CheckContextMatch(elem); + CheckContextMatch(set); + return (BoolExpr)Expr.Create(this, Native.Z3_mk_finite_set_member(nCtx, elem.NativeObject, set.NativeObject)); + } + + /// + /// Get the cardinality of a finite set. + /// + public Expr MkFiniteSetSize(Expr set) + { + Debug.Assert(set != null); + + CheckContextMatch(set); + return Expr.Create(this, Native.Z3_mk_finite_set_size(nCtx, set.NativeObject)); + } + + /// + /// Check if one finite set is a subset of another. + /// + public BoolExpr MkFiniteSetSubset(Expr s1, Expr s2) + { + Debug.Assert(s1 != null); + Debug.Assert(s2 != null); + + CheckContextMatch(s1); + CheckContextMatch(s2); + return (BoolExpr)Expr.Create(this, Native.Z3_mk_finite_set_subset(nCtx, s1.NativeObject, s2.NativeObject)); + } + + /// + /// Map a function over all elements in a finite set. + /// + public Expr MkFiniteSetMap(Expr f, Expr set) + { + Debug.Assert(f != null); + Debug.Assert(set != null); + + CheckContextMatch(f); + CheckContextMatch(set); + return Expr.Create(this, Native.Z3_mk_finite_set_map(nCtx, f.NativeObject, set.NativeObject)); + } + + /// + /// Filter a finite set with a predicate. + /// + public Expr MkFiniteSetFilter(Expr f, Expr set) + { + Debug.Assert(f != null); + Debug.Assert(set != null); + + CheckContextMatch(f); + CheckContextMatch(set); + return Expr.Create(this, Native.Z3_mk_finite_set_filter(nCtx, f.NativeObject, set.NativeObject)); + } + + /// + /// Create a finite set containing integers in the range [low, high]. + /// + public Expr MkFiniteSetRange(Expr low, Expr high) + { + Debug.Assert(low != null); + Debug.Assert(high != null); + + CheckContextMatch(low); + CheckContextMatch(high); + return Expr.Create(this, Native.Z3_mk_finite_set_range(nCtx, low.NativeObject, high.NativeObject)); + } + + #endregion + #region Sequence, string and regular expressions /// diff --git a/src/api/dotnet/FiniteSetSort.cs b/src/api/dotnet/FiniteSetSort.cs new file mode 100644 index 000000000..dda981cf9 --- /dev/null +++ b/src/api/dotnet/FiniteSetSort.cs @@ -0,0 +1,53 @@ +/*++ +Copyright (c) 2024 Microsoft Corporation + +Module Name: + + FiniteSetSort.cs + +Abstract: + + Z3 Managed API: Finite Set Sorts + +Author: + + GitHub Copilot + +Notes: + +--*/ + +using System.Diagnostics; +using System; + +namespace Microsoft.Z3 +{ + /// + /// Finite set sorts. + /// + public class FiniteSetSort : Sort + { + #region Internal + internal FiniteSetSort(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Debug.Assert(ctx != null); + } + + internal FiniteSetSort(Context ctx, Sort elemSort) + : base(ctx, Native.Z3_mk_finite_set_sort(ctx.nCtx, elemSort.NativeObject)) + { + Debug.Assert(ctx != null); + Debug.Assert(elemSort != null); + } + #endregion + + /// + /// Get the element sort (basis) of this finite set sort. + /// + public Sort Basis + { + get { return Sort.Create(Context, Native.Z3_get_finite_set_sort_basis(Context.nCtx, NativeObject)); } + } + } +} diff --git a/src/api/java/Context.java b/src/api/java/Context.java index 691ecd737..d410b5c39 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -2052,6 +2052,145 @@ public class Context implements AutoCloseable { } + /** + * Finite Sets + */ + + /** + * Create a finite set sort over the given element sort. + **/ + public final FiniteSetSort mkFiniteSetSort(Sort elemSort) + { + checkContextMatch(elemSort); + return new FiniteSetSort(this, elemSort); + } + + /** + * Check if a sort is a finite set sort. + **/ + public final boolean isFiniteSetSort(Sort s) + { + checkContextMatch(s); + return Native.isFiniteSetSort(nCtx(), s.getNativeObject()); + } + + /** + * Get the element sort (basis) of a finite set sort. + **/ + public final Sort getFiniteSetSortBasis(Sort s) + { + checkContextMatch(s); + return Sort.create(this, Native.getFiniteSetSortBasis(nCtx(), s.getNativeObject())); + } + + /** + * Create an empty finite set. + **/ + public final Expr mkFiniteSetEmpty(Sort setSort) + { + checkContextMatch(setSort); + return Expr.create(this, Native.mkFiniteSetEmpty(nCtx(), setSort.getNativeObject())); + } + + /** + * Create a singleton finite set. + **/ + public final Expr mkFiniteSetSingleton(Expr elem) + { + checkContextMatch(elem); + return Expr.create(this, Native.mkFiniteSetSingleton(nCtx(), elem.getNativeObject())); + } + + /** + * Create the union of two finite sets. + **/ + public final Expr mkFiniteSetUnion(Expr s1, Expr s2) + { + checkContextMatch(s1); + checkContextMatch(s2); + return Expr.create(this, Native.mkFiniteSetUnion(nCtx(), s1.getNativeObject(), s2.getNativeObject())); + } + + /** + * Create the intersection of two finite sets. + **/ + public final Expr mkFiniteSetIntersect(Expr s1, Expr s2) + { + checkContextMatch(s1); + checkContextMatch(s2); + return Expr.create(this, Native.mkFiniteSetIntersect(nCtx(), s1.getNativeObject(), s2.getNativeObject())); + } + + /** + * Create the difference of two finite sets. + **/ + public final Expr mkFiniteSetDifference(Expr s1, Expr s2) + { + checkContextMatch(s1); + checkContextMatch(s2); + return Expr.create(this, Native.mkFiniteSetDifference(nCtx(), s1.getNativeObject(), s2.getNativeObject())); + } + + /** + * Check for membership in a finite set. + **/ + public final BoolExpr mkFiniteSetMember(Expr elem, Expr set) + { + checkContextMatch(elem); + checkContextMatch(set); + return (BoolExpr) Expr.create(this, Native.mkFiniteSetMember(nCtx(), elem.getNativeObject(), set.getNativeObject())); + } + + /** + * Get the cardinality of a finite set. + **/ + public final Expr mkFiniteSetSize(Expr set) + { + checkContextMatch(set); + return Expr.create(this, Native.mkFiniteSetSize(nCtx(), set.getNativeObject())); + } + + /** + * Check if one finite set is a subset of another. + **/ + public final BoolExpr mkFiniteSetSubset(Expr s1, Expr s2) + { + checkContextMatch(s1); + checkContextMatch(s2); + return (BoolExpr) Expr.create(this, Native.mkFiniteSetSubset(nCtx(), s1.getNativeObject(), s2.getNativeObject())); + } + + /** + * Map a function over all elements in a finite set. + **/ + public final Expr mkFiniteSetMap(Expr f, Expr set) + { + checkContextMatch(f); + checkContextMatch(set); + return Expr.create(this, Native.mkFiniteSetMap(nCtx(), f.getNativeObject(), set.getNativeObject())); + } + + /** + * Filter a finite set with a predicate. + **/ + public final Expr mkFiniteSetFilter(Expr f, Expr set) + { + checkContextMatch(f); + checkContextMatch(set); + return Expr.create(this, Native.mkFiniteSetFilter(nCtx(), f.getNativeObject(), set.getNativeObject())); + } + + /** + * Create a finite set containing integers in the range [low, high]. + **/ + public final Expr mkFiniteSetRange(Expr low, Expr high) + { + checkContextMatch(low); + checkContextMatch(high); + return Expr.create(this, Native.mkFiniteSetRange(nCtx(), low.getNativeObject(), high.getNativeObject())); + } + + /** * Sequences, Strings and regular expressions. */ diff --git a/src/api/java/FiniteSetSort.java b/src/api/java/FiniteSetSort.java new file mode 100644 index 000000000..031199539 --- /dev/null +++ b/src/api/java/FiniteSetSort.java @@ -0,0 +1,42 @@ +/** +Copyright (c) 2024 Microsoft Corporation + +Module Name: + + FiniteSetSort.java + +Abstract: + +Author: + + GitHub Copilot + +Notes: + +**/ + +package com.microsoft.z3; + +/** + * Finite set sorts. + **/ +public class FiniteSetSort extends Sort +{ + FiniteSetSort(Context ctx, long obj) + { + super(ctx, obj); + } + + FiniteSetSort(Context ctx, Sort elemSort) + { + super(ctx, Native.mkFiniteSetSort(ctx.nCtx(), elemSort.getNativeObject())); + } + + /** + * Get the element sort (basis) of this finite set sort. + **/ + public Sort getBasis() + { + return Sort.create(getContext(), Native.getFiniteSetSortBasis(getContext().nCtx(), getNativeObject())); + } +} From f1d91f44ca3ed7d6bc43ff004d562b4e84e9a1e5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 29 Oct 2025 23:50:44 +0000 Subject: [PATCH 3/5] Add documentation and examples for finite set APIs Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> --- FINITE_SET_API_EXAMPLES.md | 140 +++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 FINITE_SET_API_EXAMPLES.md diff --git a/FINITE_SET_API_EXAMPLES.md b/FINITE_SET_API_EXAMPLES.md new file mode 100644 index 000000000..e180fb7f4 --- /dev/null +++ b/FINITE_SET_API_EXAMPLES.md @@ -0,0 +1,140 @@ +# Finite Set API Examples + +This document provides usage examples for the finite set API in Java and C#. + +## Java Example + +```java +import com.microsoft.z3.*; + +public class FiniteSetExample { + public static void main(String[] args) { + try (Context ctx = new Context()) { + // Create finite set sort over integers + Sort intSort = ctx.getIntSort(); + FiniteSetSort intSetSort = ctx.mkFiniteSetSort(intSort); + + // Check if it's a finite set sort + boolean isFiniteSet = ctx.isFiniteSetSort(intSetSort); + System.out.println("Is finite set sort: " + isFiniteSet); + + // Get the element sort (basis) + Sort basis = ctx.getFiniteSetSortBasis(intSetSort); + System.out.println("Element sort: " + basis); + + // Create sets + Expr emptySet = ctx.mkFiniteSetEmpty(intSetSort); + IntExpr one = ctx.mkInt(1); + IntExpr two = ctx.mkInt(2); + Expr singleton1 = ctx.mkFiniteSetSingleton(one); + Expr singleton2 = ctx.mkFiniteSetSingleton(two); + + // Set operations + Expr union = ctx.mkFiniteSetUnion(singleton1, singleton2); + Expr intersect = ctx.mkFiniteSetIntersect(union, singleton1); + Expr difference = ctx.mkFiniteSetDifference(union, singleton1); + + // Set queries + BoolExpr member = ctx.mkFiniteSetMember(one, union); + Expr size = ctx.mkFiniteSetSize(union); + BoolExpr subset = ctx.mkFiniteSetSubset(singleton1, union); + + // Create integer range [1..10] + Expr range = ctx.mkFiniteSetRange(ctx.mkInt(1), ctx.mkInt(10)); + + // Solve with finite sets + Solver solver = ctx.mkSolver(); + solver.add(ctx.mkFiniteSetMember(one, union)); + solver.add(ctx.mkEq(ctx.mkFiniteSetSize(union), ctx.mkInt(2))); + Status status = solver.check(); + System.out.println("Solver result: " + status); + } + } +} +``` + +## C# Example + +```csharp +using System; +using Microsoft.Z3; + +class FiniteSetExample +{ + static void Main(string[] args) + { + using (Context ctx = new Context()) + { + // Create finite set sort over integers + Sort intSort = ctx.IntSort; + FiniteSetSort intSetSort = ctx.MkFiniteSetSort(intSort); + + // Check if it's a finite set sort + bool isFiniteSet = ctx.IsFiniteSetSort(intSetSort); + Console.WriteLine($"Is finite set sort: {isFiniteSet}"); + + // Get the element sort (basis) + Sort basis = ctx.GetFiniteSetSortBasis(intSetSort); + // Or use the property: + Sort basis2 = intSetSort.Basis; + Console.WriteLine($"Element sort: {basis}"); + + // Create sets + Expr emptySet = ctx.MkFiniteSetEmpty(intSetSort); + IntExpr one = ctx.MkInt(1); + IntExpr two = ctx.MkInt(2); + Expr singleton1 = ctx.MkFiniteSetSingleton(one); + Expr singleton2 = ctx.MkFiniteSetSingleton(two); + + // Set operations + Expr union = ctx.MkFiniteSetUnion(singleton1, singleton2); + Expr intersect = ctx.MkFiniteSetIntersect(union, singleton1); + Expr difference = ctx.MkFiniteSetDifference(union, singleton1); + + // Set queries + BoolExpr member = ctx.MkFiniteSetMember(one, union); + Expr size = ctx.MkFiniteSetSize(union); + BoolExpr subset = ctx.MkFiniteSetSubset(singleton1, union); + + // Create integer range [1..10] + Expr range = ctx.MkFiniteSetRange(ctx.MkInt(1), ctx.MkInt(10)); + + // Solve with finite sets + Solver solver = ctx.MkSolver(); + solver.Add(ctx.MkFiniteSetMember(one, union)); + solver.Add(ctx.MkEq(ctx.MkFiniteSetSize(union), ctx.MkInt(2))); + Status status = solver.Check(); + Console.WriteLine($"Solver result: {status}"); + } + } +} +``` + +## API Methods + +### Sort Operations +- **Java**: `mkFiniteSetSort(Sort elemSort)`, `isFiniteSetSort(Sort s)`, `getFiniteSetSortBasis(Sort s)` +- **C#**: `MkFiniteSetSort(Sort elemSort)`, `IsFiniteSetSort(Sort s)`, `GetFiniteSetSortBasis(Sort s)` + +### Set Constructors +- **Java**: `mkFiniteSetEmpty(Sort setSort)`, `mkFiniteSetSingleton(Expr elem)`, `mkFiniteSetRange(Expr low, Expr high)` +- **C#**: `MkFiniteSetEmpty(Sort setSort)`, `MkFiniteSetSingleton(Expr elem)`, `MkFiniteSetRange(Expr low, Expr high)` + +### Set Operations +- **Java**: `mkFiniteSetUnion(Expr s1, Expr s2)`, `mkFiniteSetIntersect(Expr s1, Expr s2)`, `mkFiniteSetDifference(Expr s1, Expr s2)` +- **C#**: `MkFiniteSetUnion(Expr s1, Expr s2)`, `MkFiniteSetIntersect(Expr s1, Expr s2)`, `MkFiniteSetDifference(Expr s1, Expr s2)` + +### Set Queries +- **Java**: `mkFiniteSetMember(Expr elem, Expr set)`, `mkFiniteSetSize(Expr set)`, `mkFiniteSetSubset(Expr s1, Expr s2)` +- **C#**: `MkFiniteSetMember(Expr elem, Expr set)`, `MkFiniteSetSize(Expr set)`, `MkFiniteSetSubset(Expr s1, Expr s2)` + +### Set Transformations +- **Java**: `mkFiniteSetMap(Expr f, Expr set)`, `mkFiniteSetFilter(Expr f, Expr set)` +- **C#**: `MkFiniteSetMap(Expr f, Expr set)`, `MkFiniteSetFilter(Expr f, Expr set)` + +## Notes + +- Finite sets are distinct from array-based sets and provide a more direct representation +- The finite set sort extends `Sort` directly (not `ArraySort`) +- All operations follow the SMT-LIB2 finite set theory syntax +- Native bindings are auto-generated from the C API during build From 8871390b5cf171925a9c4158fd12fc6a37e5f80d Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 29 Oct 2025 16:54:16 -0700 Subject: [PATCH 4/5] Delete FINITE_SET_API_EXAMPLES.md --- FINITE_SET_API_EXAMPLES.md | 140 ------------------------------------- 1 file changed, 140 deletions(-) delete mode 100644 FINITE_SET_API_EXAMPLES.md diff --git a/FINITE_SET_API_EXAMPLES.md b/FINITE_SET_API_EXAMPLES.md deleted file mode 100644 index e180fb7f4..000000000 --- a/FINITE_SET_API_EXAMPLES.md +++ /dev/null @@ -1,140 +0,0 @@ -# Finite Set API Examples - -This document provides usage examples for the finite set API in Java and C#. - -## Java Example - -```java -import com.microsoft.z3.*; - -public class FiniteSetExample { - public static void main(String[] args) { - try (Context ctx = new Context()) { - // Create finite set sort over integers - Sort intSort = ctx.getIntSort(); - FiniteSetSort intSetSort = ctx.mkFiniteSetSort(intSort); - - // Check if it's a finite set sort - boolean isFiniteSet = ctx.isFiniteSetSort(intSetSort); - System.out.println("Is finite set sort: " + isFiniteSet); - - // Get the element sort (basis) - Sort basis = ctx.getFiniteSetSortBasis(intSetSort); - System.out.println("Element sort: " + basis); - - // Create sets - Expr emptySet = ctx.mkFiniteSetEmpty(intSetSort); - IntExpr one = ctx.mkInt(1); - IntExpr two = ctx.mkInt(2); - Expr singleton1 = ctx.mkFiniteSetSingleton(one); - Expr singleton2 = ctx.mkFiniteSetSingleton(two); - - // Set operations - Expr union = ctx.mkFiniteSetUnion(singleton1, singleton2); - Expr intersect = ctx.mkFiniteSetIntersect(union, singleton1); - Expr difference = ctx.mkFiniteSetDifference(union, singleton1); - - // Set queries - BoolExpr member = ctx.mkFiniteSetMember(one, union); - Expr size = ctx.mkFiniteSetSize(union); - BoolExpr subset = ctx.mkFiniteSetSubset(singleton1, union); - - // Create integer range [1..10] - Expr range = ctx.mkFiniteSetRange(ctx.mkInt(1), ctx.mkInt(10)); - - // Solve with finite sets - Solver solver = ctx.mkSolver(); - solver.add(ctx.mkFiniteSetMember(one, union)); - solver.add(ctx.mkEq(ctx.mkFiniteSetSize(union), ctx.mkInt(2))); - Status status = solver.check(); - System.out.println("Solver result: " + status); - } - } -} -``` - -## C# Example - -```csharp -using System; -using Microsoft.Z3; - -class FiniteSetExample -{ - static void Main(string[] args) - { - using (Context ctx = new Context()) - { - // Create finite set sort over integers - Sort intSort = ctx.IntSort; - FiniteSetSort intSetSort = ctx.MkFiniteSetSort(intSort); - - // Check if it's a finite set sort - bool isFiniteSet = ctx.IsFiniteSetSort(intSetSort); - Console.WriteLine($"Is finite set sort: {isFiniteSet}"); - - // Get the element sort (basis) - Sort basis = ctx.GetFiniteSetSortBasis(intSetSort); - // Or use the property: - Sort basis2 = intSetSort.Basis; - Console.WriteLine($"Element sort: {basis}"); - - // Create sets - Expr emptySet = ctx.MkFiniteSetEmpty(intSetSort); - IntExpr one = ctx.MkInt(1); - IntExpr two = ctx.MkInt(2); - Expr singleton1 = ctx.MkFiniteSetSingleton(one); - Expr singleton2 = ctx.MkFiniteSetSingleton(two); - - // Set operations - Expr union = ctx.MkFiniteSetUnion(singleton1, singleton2); - Expr intersect = ctx.MkFiniteSetIntersect(union, singleton1); - Expr difference = ctx.MkFiniteSetDifference(union, singleton1); - - // Set queries - BoolExpr member = ctx.MkFiniteSetMember(one, union); - Expr size = ctx.MkFiniteSetSize(union); - BoolExpr subset = ctx.MkFiniteSetSubset(singleton1, union); - - // Create integer range [1..10] - Expr range = ctx.MkFiniteSetRange(ctx.MkInt(1), ctx.MkInt(10)); - - // Solve with finite sets - Solver solver = ctx.MkSolver(); - solver.Add(ctx.MkFiniteSetMember(one, union)); - solver.Add(ctx.MkEq(ctx.MkFiniteSetSize(union), ctx.MkInt(2))); - Status status = solver.Check(); - Console.WriteLine($"Solver result: {status}"); - } - } -} -``` - -## API Methods - -### Sort Operations -- **Java**: `mkFiniteSetSort(Sort elemSort)`, `isFiniteSetSort(Sort s)`, `getFiniteSetSortBasis(Sort s)` -- **C#**: `MkFiniteSetSort(Sort elemSort)`, `IsFiniteSetSort(Sort s)`, `GetFiniteSetSortBasis(Sort s)` - -### Set Constructors -- **Java**: `mkFiniteSetEmpty(Sort setSort)`, `mkFiniteSetSingleton(Expr elem)`, `mkFiniteSetRange(Expr low, Expr high)` -- **C#**: `MkFiniteSetEmpty(Sort setSort)`, `MkFiniteSetSingleton(Expr elem)`, `MkFiniteSetRange(Expr low, Expr high)` - -### Set Operations -- **Java**: `mkFiniteSetUnion(Expr s1, Expr s2)`, `mkFiniteSetIntersect(Expr s1, Expr s2)`, `mkFiniteSetDifference(Expr s1, Expr s2)` -- **C#**: `MkFiniteSetUnion(Expr s1, Expr s2)`, `MkFiniteSetIntersect(Expr s1, Expr s2)`, `MkFiniteSetDifference(Expr s1, Expr s2)` - -### Set Queries -- **Java**: `mkFiniteSetMember(Expr elem, Expr set)`, `mkFiniteSetSize(Expr set)`, `mkFiniteSetSubset(Expr s1, Expr s2)` -- **C#**: `MkFiniteSetMember(Expr elem, Expr set)`, `MkFiniteSetSize(Expr set)`, `MkFiniteSetSubset(Expr s1, Expr s2)` - -### Set Transformations -- **Java**: `mkFiniteSetMap(Expr f, Expr set)`, `mkFiniteSetFilter(Expr f, Expr set)` -- **C#**: `MkFiniteSetMap(Expr f, Expr set)`, `MkFiniteSetFilter(Expr f, Expr set)` - -## Notes - -- Finite sets are distinct from array-based sets and provide a more direct representation -- The finite set sort extends `Sort` directly (not `ArraySort`) -- All operations follow the SMT-LIB2 finite set theory syntax -- Native bindings are auto-generated from the C API during build From f234acd7d9cb6e7f71e95350c255daab969b2754 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Oct 2025 15:47:32 +0000 Subject: [PATCH 5/5] Add FiniteSetSort files to CMakeLists.txt build configurations Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> --- src/api/dotnet/CMakeLists.txt | 1 + src/api/java/CMakeLists.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/src/api/dotnet/CMakeLists.txt b/src/api/dotnet/CMakeLists.txt index d3cb87bc7..c309f4027 100644 --- a/src/api/dotnet/CMakeLists.txt +++ b/src/api/dotnet/CMakeLists.txt @@ -64,6 +64,7 @@ set(Z3_DOTNET_ASSEMBLY_SOURCES_IN_SRC_TREE FiniteDomainExpr.cs FiniteDomainNum.cs FiniteDomainSort.cs + FiniteSetSort.cs Fixedpoint.cs FPExpr.cs FPNum.cs diff --git a/src/api/java/CMakeLists.txt b/src/api/java/CMakeLists.txt index c5221014f..2afd6ad56 100644 --- a/src/api/java/CMakeLists.txt +++ b/src/api/java/CMakeLists.txt @@ -115,6 +115,7 @@ set(Z3_JAVA_JAR_SOURCE_FILES FiniteDomainExpr.java FiniteDomainNum.java FiniteDomainSort.java + FiniteSetSort.java Fixedpoint.java FPExpr.java FPNum.java