mirror of
https://github.com/Z3Prover/z3
synced 2026-03-15 17:49:59 +00:00
Add missing AST query methods to Java API (#8977)
* add Expr.isGround() to Java API Expose Z3_is_ground as a public method on Expr. Returns true when the expression contains no free variables. * add Expr.isLambda() to Java API Expose Z3_is_lambda as a public method on Expr. Returns true when the expression is a lambda quantifier. * add AST.getDepth() to Java API Expose Z3_get_depth as a public method on AST. Returns the maximum number of nodes on any path from root to leaf. * add ArraySort.getArity() to Java API Expose Z3_get_array_arity as a public method on ArraySort. Returns the number of dimensions of a multi-dimensional array sort. * add DatatypeSort.isRecursive() to Java API Expose Z3_is_recursive_datatype_sort as a public method on DatatypeSort. Returns true when the datatype refers to itself. * add FPExpr.isNumeral() to Java API Expose Z3_fpa_is_numeral as a public method on FPExpr. Returns true when the expression is a concrete floating-point value. * add isGroundExample test to JavaExample Test Expr.isGround() on constants, variables, and compound expressions. * add astDepthExample test to JavaExample Test AST.getDepth() on leaf nodes and nested expressions to verify the depth computation. * add arrayArityExample test to JavaExample Test ArraySort.getArity() on single-domain and multi-domain array sorts. * add recursiveDatatypeExample test to JavaExample Test DatatypeSort.isRecursive() on a recursive list datatype and a non-recursive pair datatype. * add fpNumeralExample test to JavaExample Test FPExpr.isNumeral() on a floating point constant and a symbolic variable. * add isLambdaExample test to JavaExample Test Expr.isLambda() on a lambda expression and a plain variable.
This commit is contained in:
parent
6e5971641f
commit
b8e15f2121
6 changed files with 205 additions and 1 deletions
|
|
@ -2277,6 +2277,143 @@ class JavaExample
|
|||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
void isGroundExample(Context ctx) throws TestFailedException
|
||||
{
|
||||
System.out.println("IsGroundExample");
|
||||
Log.append("IsGroundExample");
|
||||
|
||||
// a constant integer is ground
|
||||
IntExpr five = ctx.mkInt(5);
|
||||
if (!five.isGround())
|
||||
throw new TestFailedException();
|
||||
|
||||
// a free variable is not ground
|
||||
IntExpr x = ctx.mkIntConst("x");
|
||||
if (!x.isGround())
|
||||
throw new TestFailedException();
|
||||
|
||||
// an addition of constants is ground
|
||||
Expr sum = ctx.mkAdd(ctx.mkInt(1), ctx.mkInt(2));
|
||||
if (!sum.isGround())
|
||||
throw new TestFailedException();
|
||||
|
||||
System.out.println("IsGroundExample passed.");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
void astDepthExample(Context ctx) throws TestFailedException
|
||||
{
|
||||
System.out.println("AstDepthExample");
|
||||
Log.append("AstDepthExample");
|
||||
|
||||
// a plain integer constant has depth 1
|
||||
IntExpr five = ctx.mkInt(5);
|
||||
if (five.getDepth() != 1)
|
||||
throw new TestFailedException();
|
||||
|
||||
// (x + 1) should have depth 2
|
||||
IntExpr x = ctx.mkIntConst("x");
|
||||
Expr sum = ctx.mkAdd(x, ctx.mkInt(1));
|
||||
if (sum.getDepth() != 2)
|
||||
throw new TestFailedException();
|
||||
|
||||
// nested: (x + 1) * y should have depth 3
|
||||
IntExpr y = ctx.mkIntConst("y");
|
||||
Expr prod = ctx.mkMul(sum, y);
|
||||
if (prod.getDepth() != 3)
|
||||
throw new TestFailedException();
|
||||
|
||||
System.out.println("AstDepthExample passed.");
|
||||
}
|
||||
|
||||
void arrayArityExample(Context ctx) throws TestFailedException
|
||||
{
|
||||
System.out.println("ArrayArityExample");
|
||||
Log.append("ArrayArityExample");
|
||||
|
||||
// Array Int -> Int has arity 1
|
||||
ArraySort<IntSort, IntSort> arr1 = ctx.mkArraySort(ctx.getIntSort(), ctx.getIntSort());
|
||||
if (arr1.getArity() != 1)
|
||||
throw new TestFailedException();
|
||||
|
||||
// Array (Int, Bool) -> Int has arity 2
|
||||
ArraySort arr2 = ctx.mkArraySort(new Sort[]{ctx.getIntSort(), ctx.getBoolSort()}, ctx.getIntSort());
|
||||
if (arr2.getArity() != 2)
|
||||
throw new TestFailedException();
|
||||
|
||||
System.out.println("ArrayArityExample passed.");
|
||||
}
|
||||
|
||||
void recursiveDatatypeExample(Context ctx) throws TestFailedException
|
||||
{
|
||||
System.out.println("RecursiveDatatypeExample");
|
||||
Log.append("RecursiveDatatypeExample");
|
||||
|
||||
// a list sort is recursive (cons refers back to the list)
|
||||
Constructor<Sort> nil = ctx.mkConstructor("nil", "is_nil", null, null, null);
|
||||
Constructor<Sort> cons = ctx.mkConstructor("cons", "is_cons",
|
||||
new String[]{"head", "tail"},
|
||||
new Sort[]{ctx.getIntSort(), null},
|
||||
new int[]{0, 0});
|
||||
DatatypeSort<Sort> intList = ctx.mkDatatypeSort("intlist", new Constructor[]{nil, cons});
|
||||
if (!intList.isRecursive())
|
||||
throw new TestFailedException();
|
||||
|
||||
// a simple pair sort is not recursive
|
||||
Constructor<Sort> mkPair = ctx.mkConstructor("mkpair", "is_pair",
|
||||
new String[]{"fst", "snd"},
|
||||
new Sort[]{ctx.getIntSort(), ctx.getBoolSort()},
|
||||
null);
|
||||
DatatypeSort<Sort> pair = ctx.mkDatatypeSort("Pair", new Constructor[]{mkPair});
|
||||
if (pair.isRecursive())
|
||||
throw new TestFailedException();
|
||||
|
||||
System.out.println("RecursiveDatatypeExample passed.");
|
||||
}
|
||||
|
||||
void fpNumeralExample(Context ctx) throws TestFailedException
|
||||
{
|
||||
System.out.println("FpNumeralExample");
|
||||
Log.append("FpNumeralExample");
|
||||
|
||||
FPSort fpsort = ctx.mkFPSort32();
|
||||
|
||||
// a floating point numeral
|
||||
FPExpr fpval = (FPExpr) ctx.mkFP(3.14, fpsort);
|
||||
if (!fpval.isNumeral())
|
||||
throw new TestFailedException();
|
||||
|
||||
// a symbolic FP variable is not a numeral
|
||||
FPExpr fpvar = (FPExpr) ctx.mkConst("fpx", fpsort);
|
||||
if (fpvar.isNumeral())
|
||||
throw new TestFailedException();
|
||||
|
||||
System.out.println("FpNumeralExample passed.");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
void isLambdaExample(Context ctx) throws TestFailedException
|
||||
{
|
||||
System.out.println("IsLambdaExample");
|
||||
Log.append("IsLambdaExample");
|
||||
|
||||
// build lambda x : Int . x + 1
|
||||
IntExpr x = (IntExpr) ctx.mkBound(0, ctx.getIntSort());
|
||||
Expr body = ctx.mkAdd(x, ctx.mkInt(1));
|
||||
Expr lam = ctx.mkLambda(new Sort[]{ctx.getIntSort()},
|
||||
new Symbol[]{ctx.mkSymbol("x")}, body);
|
||||
if (!lam.isLambda())
|
||||
throw new TestFailedException();
|
||||
|
||||
// a regular expression is not a lambda
|
||||
IntExpr y = ctx.mkIntConst("y");
|
||||
if (y.isLambda())
|
||||
throw new TestFailedException();
|
||||
|
||||
System.out.println("IsLambdaExample passed.");
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
JavaExample p = new JavaExample();
|
||||
|
|
@ -2328,6 +2465,12 @@ class JavaExample
|
|||
p.finiteDomainExample(ctx);
|
||||
p.floatingPointExample1(ctx);
|
||||
// core dumps: p.floatingPointExample2(ctx);
|
||||
p.isGroundExample(ctx);
|
||||
p.astDepthExample(ctx);
|
||||
p.arrayArityExample(ctx);
|
||||
p.recursiveDatatypeExample(ctx);
|
||||
p.fpNumeralExample(ctx);
|
||||
p.isLambdaExample(ctx);
|
||||
}
|
||||
|
||||
{ // These examples need proof generation turned on.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue