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

Checking for unsatisfiability when using ValueTuple #28

Open
NickRedwood opened this issue Aug 2, 2023 · 2 comments
Open

Checking for unsatisfiability when using ValueTuple #28

NickRedwood opened this issue Aug 2, 2023 · 2 comments

Comments

@NickRedwood
Copy link

NickRedwood commented Aug 2, 2023

Hi, thanks for publishing this library.

I found an issue with checking for unsatisfiability when using ValueTuple, as it will return the default all-zero. This is ambiguous as that could be a valid solution, or it could mean unsatisfiable.

using (var ctx = new Z3Context())
{
	
	var theorem = from t in ctx.NewTheorem<(int a, int b)>()
				  where t.a == t.b
				  where t.a > 4
				  where t.b < 2
				  select t;
	
	var result = theorem.Solve();
	
	Console.WriteLine(result);
	// (0,0)
}

Is there a better way?

I explored and found that it's possible to provide a nullable ValueTuple, though this then requires accessing Value explicitly everywhere.

	var theorem2 = from t in ctx.NewTheorem<(int a, int b)?>()
				  where t.Value.a == t.Value.b
				  where t.Value.a > 4
				  where t.Value.b < 2
				  select t;

	var result2 = theorem2.Solve();
	Console.WriteLine(result2);
	// null

Perhaps an improvement could be to provide an overload of Solve or NewTheorem for struct types that lifts them to Nullable?

@idg10
Copy link
Contributor

idg10 commented Aug 11, 2023

Here's a hacky sort of a workaround:

var theorem = from t in ctx.NewTheorem<(int a, int b, bool solved)>()
              where t.a == t.b
              where t.a > 4
              where t.b < 2
              where t.solved == true
              select t;

var result = theorem.Solve();

Console.WriteLine(result.solved ? result.ToString() : "Not solved");

Since default(bool) is false, the solved property will be true only if it found a solution.

But this does make me think that maybe what this really needs is a TrySolve method that tells you whether it succeeded, so that we don't need to rely on detecting failing by looking for a default result.

@NickRedwood
Copy link
Author

Thanks, that's a clever workaround - even if a little hacky it's better than my Nullable solution I think. A TrySolve type of method would work well in future though.

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