Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java API: ClassCastException when getting EnumSort of constant #7335

Open
mmsbrggr opened this issue Aug 9, 2024 · 1 comment
Open

Java API: ClassCastException when getting EnumSort of constant #7335

mmsbrggr opened this issue Aug 9, 2024 · 1 comment

Comments

@mmsbrggr
Copy link

mmsbrggr commented Aug 9, 2024

Consider the following scenario using the Java API: We declare a new enum-sort E and a new constant C whose sort is E.

If we now try to get the sort of C the API doesn't return an EnumSort but a DatatypeSort. If we now call a method such as getName of the returned sort the application throws a ClassCastException.

Here is a minimal example:

import com.microsoft.z3.Context;
import com.microsoft.z3.EnumSort;
import com.microsoft.z3.Expr;

public class Minimal {

    public static void main(String[] args) {
        Context ctx = new Context();
        EnumSort<Minimal> enumSort = ctx.mkEnumSort("my-enum", "e1", "e2");
        Expr<EnumSort<Minimal>> myConst = ctx.mkConst("my-const", enumSort);
        System.out.println(myConst.getSort().getName());
        ctx.close();
    }
}

Behavior: throws ClassCastException
Expected: prints "my-enum"

@intrigus-lgtm
Copy link
Contributor

There is no such thing as an "EnumSort" in the core z3 api:

z3/src/api/z3_api.h

Lines 137 to 155 in 6086a30

typedef enum
{
Z3_UNINTERPRETED_SORT,
Z3_BOOL_SORT,
Z3_INT_SORT,
Z3_REAL_SORT,
Z3_BV_SORT,
Z3_ARRAY_SORT,
Z3_DATATYPE_SORT,
Z3_RELATION_SORT,
Z3_FINITE_DOMAIN_SORT,
Z3_FLOATING_POINT_SORT,
Z3_ROUNDING_MODE_SORT,
Z3_SEQ_SORT,
Z3_RE_SORT,
Z3_CHAR_SORT,
Z3_TYPE_VAR,
Z3_UNKNOWN_SORT = 1000
} Z3_sort_kind;

it's all syntactic sugar for a DatatypeSort.

So when you call getSort, it calls the native API and that API can only ever return DatatypeSort.

So if you actually need to check whether the sort of a constant was an EnumSort, it is my understanding that you are out of luck.
If you just want to make your code work, it should be enough to cast the result of myConst.getSort() to Sort like so:
((Sort)myConst.getSort()).getName().

Why does Java claim that getSort returns an EnumSort when it doesn't?
This cast here is the reason:

z3/src/api/java/Expr.java

Lines 239 to 243 in 6086a30

public R getSort()
{
return (R) Sort.create(getContext(),
Native.getSort(getContext().nCtx(), getNativeObject()));
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants