Strange result when I ask Z3 for additional solutions - z3

I am using Z3 as a simple SAT solver, asserting propositional terms as follows:
let ctx = new Context()
let x = ctx.MkBoolConst("x")
let y = ctx.MkBoolConst("y")
let z = ctx.MkBoolConst("z")
let f = ctx.MkOr(ctx.MkAnd(x,y), ctx.MkAnd(ctx.MkNot(x),z))
let s = ctx.MkSolver()
s.Assert(f)
assert (s.Check() = Status.SATISFIABLE)
let r= [s.Model.Eval(x); s.Model.Eval(y); s.Model.Eval(z)]
printfn "%A" r
Which returns
[false; true; true]
as expected. However, when i try to ask Z3 for further solutions by taking the and of the found assignments and negating that and adding it back to Z3 solver
let mkB(z3_lit:BoolExpr,bvalue:Expr) =
if (bvalue:?> BoolExpr).IsTrue then z3_lit else ctx.MkNot z3_lit
let founds = List.map mkB (List.zip [x;y;z] r)
let and_founds = ctx.MkAnd (List.toArray(founds))
let negated = ctx.MkNot and_founds
s.Assert negated
assert (s.Check() = Status.SATISFIABLE)
let r2 = [s.Model.Eval(x); s.Model.Eval(y); s.Model.Eval(z)]
printfn "%A" r2
I get a strange assignment to z. ie:
[true; true; z]
Why is the assignment to z which was previously true changed to z?

If I'm not mistaken, getting a variable as its own model means it's a "don't care": any value for z will give you a valid model. Indeed, in this case, the clause is already satisfied by x and y being true.
If you want Z3 to complete the model for you, you can take a look at this question.
Also, the C API at least defines an extra argument to Z3_model_eval, which you can use to indicate to Z3 that you want a value for all variables.

Related

F# Or-Tools Sat Solver

I am experimenting with F# and want to do some constraint programming where I use Or-Tools. I have previously used the package together with Python, but I can’t get it to work with F#.
I follow the C# example: https://developers.google.com/optimization/cp/cp_solver#c_5
But get an error when try to add a constraint:
So this is kind of annoying, but it's how consuming operators that were overloaded in C# from F# works.
The reason why you couldn't use != like this is because:
The operator != is (and this is unusual) overloaded in C# as a static operator on the LinearExpr class.
The operator != compiles down to op_Inequality, but op_Inequality in F# is <>, not !=
F# already defines <> as a generic operator that accepts any member that satisfies the equality constraint, which LinearExpr does
The defined operator <> resolves correctly, and produces a bool, which is incompatible with model.Add because it doesn't expect a bool
The solution is to explicitly qualify your access to the operator like so:
LinearExpr.(<>) (x, y)
Note that because it takes tupled arguments in its definition, you must also tuple your arguments and you can't use it like a "normal" operator.
Here is the full F# solution, with a few small tweaks to make it idiomatic:
#r "nuget: Google.OrTools"
open Google.OrTools.Sat
let model = CpModel()
// Creates the variables.
let num_vals = 3L;
let x = model.NewIntVar(0L, num_vals - 1L, "x")
let y = model.NewIntVar(0L, num_vals - 1L, "y")
let z = model.NewIntVar(0L, num_vals - 1L, "z")
// Creates the constraints.
model.Add(LinearExpr.(<>) (x, y))
// Creates a solver and solves the model.
let solver = CpSolver();
let status = solver.Solve(model)
if status = CpSolverStatus.Optimal then
printfn $"x = {solver.Value(x)}"
printfn $"y = {solver.Value(y)}"
printfn $"z = {solver.Value(z)}"
A way to make this a bit nicer from F# is to define a module of operators that map to the LinearExpr operators like so:
module LinearExprOperators =
let ( ^<> ) (x: LinearExpr) (y: LinearExpr) = LinearExpr.(<>) (x, y)
let ( ^= ) (x: LinearExpr) (y: LinearExpr) = LinearExpr.(=) (x, y)
Then you can use those operators instead. Another annoyance is that it appears that + and - and * work just fine, because the F# type doesn't produce a different type like bool.
So in short, this particular API is a little annoying to use from F#.

How do I check for reference equality in F#?

F# uses structural equality for the = operator, which is almost always what you want:
let a = [1; 2; 3]
let b = [1; 2; 3]
printfn "%A" (a = b) // Prints "true"
But in some algorithms, it can be important to be able to ask "Are these two things the same object?" This can help with detecting cycles in a graph, for example. So how do I ask for reference equality in F#? I.e., how do I write the isSameObject function below?
let isSameObject x y = ???
let a = [1; 2; 3]
let b = [1; 2; 3]
let a' = a
printfn "%A" (isSameObject a b) // Prints "false"
printfn "%A" (isSameObject a a') // Prints "true"
The answer, it turns out, is to use LanguagePrimitives.PhysicalEquality:
let isSameObject = LanguagePrimitives.PhysicalEquality
let a = [1; 2; 3]
let b = [1; 2; 3]
let a' = a
printfn "%A" (isSameObject a b) // Prints "false"
printfn "%A" (isSameObject a a') // Prints "true"
There was precisely one question I could find on Stack Overflow that asked about this:
short-cutting equality checking in F#? And since that question's subject almost made me glance right past it, I figured I would ask (and answer) the question again. Hopefully this question's subject line will make it easier to find when Googling for terms like "referential equality in F#".
What about obj.ReferenceEquals?
In a comment, Fyodor Soikin asks what's wrong with obj.ReferenceEquals. The answer is "not much", but there are two ways in which LanguagePrimitives.PhysicalEquality is better than obj.ReferenceEquals for most F# code:
1) PhysicalEquality throws a compiler error when you pass it two different types, while obj.ReferenceEquals just takes two objs and therefore happily tries to compare an int list to char list:
let a = [1;2;3]
let b = ['a';'b';'c']
obj.ReferenceEquals(a,b) // Returns false
LanguagePrimitives.PhysicalEquality a b // Compiler error
2) PhysicalEquality won't let you compare value types, only reference types. obj.ReferenceEquals will let you compare two value types, and will implicitly box them first. But it boxes each one separately, meaning that it will always return false even when you gave it the "same" value object:
let n = 3
let n' = n
obj.ReferenceEquals(n,n') // Returns false!
LanguagePrimitives.PhysicalEquality n n' // Compiler error
And, of course, there's one other difference, which boils down to personal preference and ease-of-use. PhysicalEquality takes curried-style parameters, which plays nicely with type inference and partial application. obj.ReferenceEquals takes tupled-style parameters, which means it's slightly uglier to use.
For all these reasons, LanguagePrimitives.PhysicalEquality is better to use, in almost every scenario, than obj.ReferenceEquals.

Verifying a set of objects have been mapped correctly

I'm looking for a clean set of ways to manage Test Specific Equality in F# unit tests. 90% of the time, the standard Structural Equality fits the bill and I can leverage it with unquote to express the relation between my result and my expected.
TL;DR "I can't find a clean way to having a custom Equality function for one or two properties in a value which 90% of is well served by Structural Equality, does F# have a way to match an arbitrary record with custom Equality for just one or two of its fields?"
Example of a general technique that works for me
When verifying a function that performs a 1:1 mapping of a datatype to another, I'll often extract matching tuples from both sides of in some cases and compare the input and output sets. For example, I have an operator:-
let (====) x y = (x |> Set.ofSeq) = (y |> Set.ofSeq)
So I can do:
let inputs = ["KeyA",DateTime.Today; "KeyB",DateTime.Today.AddDays(1); "KeyC",DateTime.Today.AddDays(2)]
let trivialFun (a:string,b) = a.ToLower(),b
let expected = inputs |> Seq.map trivialFun
let result = inputs |> MyMagicMapper
test <# expected ==== actual #>
This enables me to Assert that each of my inputs has been mapped to an output, without any superfluous outputs.
The problem
The problem is when I want to have a custom comparison for one or two of the fields.
For example, if my DateTime is being passed through a slightly lossy serialization layer by the SUT, I need a test-specific tolerant DateTime comparison. Or maybe I want to do a case-insensitive verification for a string field
Normally, I'd use Mark Seemann's SemanticComparison library's Likeness<Source,Destination> to define a Test Specific equality, but I've run into some roadblocks:
tuples: F# hides .ItemX on Tuple so I can't define the property via a .With strongly typed field name Expression<T>
record types: TTBOMK these are sealed by F# with no opt-out so SemanticComparison can't proxy them to override Object.Equals
My ideas
All I can think of is to create a generic Resemblance proxy type that I can include in a tuple or record.
Or maybe using pattern matching (Is there a way I can use that to generate an IEqualityComparer and then do a set comparison using that?)
Alternate failing test
I'm also open to using some other function to verify the full mapping (i.e. not abusing F# Set or involving too much third party code. i.e. something to make this pass:
let sut (a:string,b:DateTime) = a.ToLower(),b + TimeSpan.FromTicks(1L)
let inputs = ["KeyA",DateTime.Today; "KeyB",DateTime.Today.AddDays(1.0); "KeyC",DateTime.Today.AddDays(2.0)]
let toResemblance (a,b) = TODO generate Resemblance which will case insensitively compare fst and tolerantly compare snd
let expected = inputs |> List.map toResemblance
let result = inputs |> List.map sut
test <# expected = result #>
Firstly, thanks to all for the inputs. I was largely unaware of SemanticComparer<'T> and it definitely provides a good set of building blocks for building generalized facilities in this space. Nikos' post gives excellent food for thought in the area too. I shouldn't have been surprised Fil exists too - #ptrelford really does have a lib for everything (the FSharpValue point is also v valuable)!
We've thankfully arrived at a conclusion to this. Unfortunately it's not a single all-encompassing tool or technique, but even better, a set of techniques that can be used as necessary in a given context.
Firstly, the issue of ensuring a mapping is complete is really an orthogonal concern. The question refers to an ==== operator:-
let (====) x y = (x |> Set.ofSeq) = (y |> Set.ofSeq)
This is definitely the best default approach - lean on Structural Equality. One thing to note is that, being reliant on F# persistent sets, it requires your type to support : comparison (as opposed to just : equality).
When doing set comparisons off the proven Structural Equality path, a useful technique is to use HashSet<T> with a custom IEqualityComparer:-
[<AutoOpen>]
module UnorderedSeqComparisons =
let seqSetEquals ec x y =
HashSet<_>( x, ec).SetEquals( y)
let (==|==) x y equals =
let funEqualityComparer = {
new IEqualityComparer<_> with
member this.GetHashCode(obj) = 0
member this.Equals(x,y) =
equals x y }
seqSetEquals funEqualityComparer x y
the equals parameter of ==|== is 'a -> 'a -> bool which allows one to use pattern matching to destructure args for the purposes of comparison. This works well if either the input or the result side are naturally already tuples. Example:
sut.Store( inputs)
let results = sut.Read()
let expecteds = seq { for x in inputs -> x.Name,x.ValidUntil }
test <# expecteds ==|== results
<| fun (xN,xD) (yN,yD) ->
xF=yF
&& xD |> equalsWithinASecond <| yD #>
While SemanticComparer<'T> can do a job, it's simply not worth bothering for tuples with when you have the power of pattern matching. e.g. Using SemanticComparer<'T>, the above test can be expressed as:
test <# expecteds ==~== results
<| [ funNamedMemberComparer "Item2" equalsWithinASecond ] #>
using the helper:
[<AutoOpen>]
module MemberComparerHelpers =
let funNamedMemberComparer<'T> name equals = {
new IMemberComparer with
member this.IsSatisfiedBy(request: PropertyInfo) =
request.PropertyType = typedefof<'T>
&& request.Name = name
member this.IsSatisfiedBy(request: FieldInfo) =
request.FieldType = typedefof<'T>
&& request.Name = name
member this.GetHashCode(obj) = 0
member this.Equals(x, y) =
equals (x :?> 'T) (y :?> 'T) }
let valueObjectMemberComparer() = {
new IMemberComparer with
member this.IsSatisfiedBy(request: PropertyInfo) = true
member this.IsSatisfiedBy(request: FieldInfo) = true
member this.GetHashCode(obj) = hash obj
member this.Equals(x, y) =
x.Equals( y) }
let (==~==) x y mcs =
let ec = SemanticComparer<'T>( seq {
yield valueObjectMemberComparer()
yield! mcs } )
seqSetEquals ec x y
All of the above is best understood by reading Nikos Baxevanis' post NOW!
For types or records, the ==|== technique can work (except critically you lose Likeness<'T>s verifying coverage of fields). However the succinctness can make it a valuable tool for certain sorts of tests :-
sut.Save( inputs)
let expected = inputs |> Seq.map (fun x -> Mapped( base + x.ttl, x.Name))
let likeExpected x = expected ==|== x <| (fun x y -> x.Name = y.Name && x.ValidUntil = y.ValidUntil)
verify <# repo.Store( is( likeExpected)) #> once

Generic type annotation in F#

I got the following error:
Error 2 Value restriction. The value 'gbmLikelihood' has been inferred to have generic type val gbmLikelihood : (float -> '_a -> float [] -> float) when '_a :> seq<float> Either make the arguments to 'gbmLikelihood' explicit or, if you do not intend for it to be generic, add a type annotation.
and this type is exactly what I want. What do I have to do to make it work, and why doesn't it just work without intervention?
EDIT:
The error comes from this file (its short, so I paste the whole lot):
module Likelihood
open System
let likelihood getDrift getVol dt data parameters =
let m = getDrift data parameters
let s = getVol data parameters
let N = float (Seq.length data)
let sqrt_dt = Math.Sqrt dt
let constant = -0.5*Math.Log(2.0*Math.PI*dt)*N
let normalizedResidue observation = (observation - (m - 0.5*s*s)*dt)/(s*sqrt_dt)
let residueSquared observation =
let r = normalizedResidue observation in r*r
let logStdDev = Math.Log s
constant - logStdDev*N - 0.5* (data |> Seq.sumBy residueSquared)
let gbmLikelihood = likelihood (fun data p -> Array.get p 0) (fun datac p -> Array.get p 1)
This error can happen when you declare a value that has a generic type. See for example this past SO question. In your case, the type suggests that you are trying to define a function, but the compiler does not see it as a syntactic function. This can happen if you perform some effects and then return function using the lambda syntax:
let wrong =
printfn "test"
(fun x -> x)
To avoid the problem, you need to write the function using the function syntax:
printfn "test"
let wrong x = x
EDIT: In your concrete example, the function gbmLikelihood is created as a result of a partial function application. To make it compile, you need to turn it into an explicit function:
let gbmLikelihood parameters =
likelihood (fun data p -> Array.get p 0) (fun datac p -> Array.get p 1) parameters
For more information why this is the case & how it works, see also this great article on value restriction in F#.
Instead of making the parameters of gbmLikelihood explicit you might also just add a generic type annotation to the function:
let gbmLikelihood<'a> =
likelihood (fun data p -> Array.get p 0) (fun datac p -> Array.get p 1)

functions in F# .. why is it not compiling

I have written two versions of code. The first one works as expected and print "Hi". the second one gives me error that "block following this let is unfinished"
1st version
#light
let samplefn() =
let z = 2
let z = z * 2
printfn "hi"
samplefn()
2nd version
#light
let samplefn() =
let z = 2
let z = z * 2
samplefn()
Only difference is the printfn is absent in the second version. I am using Visual Studio 2010 as my IDE. I am very new to F# but this error seems very strange to me. I guess I am missing some very important concept. Please explain.
Edit: Also if I do it outside the function I get error even with the first version of code.
#light
let z = 2
let z = z * 2
printfn "Error: Duplicate definition of value z"
let binds a value to a label but otherwise doesn't do much else. Your function contains two bindings but doesn't use them, and so you get an error.
To think of it another way, all functions in F# need a return value, which is the value of the last executed expression in your function. let doesn't have a return value so your function is invalid. To fix this you can add a return value, for example:
let samplefn() =
let z = 2
let z = z * 2
()
which defines a function that does absolutely nothing (returns unit). Perhaps a better example is this:
let samplefn() =
let z = 2
let z = z * 2
z
which will return 4 (the value of the binding for label z).
I think it is helpful to understand the non-light syntax here. Let's translate:
1st Version (let binding expressions)
let samplefn() =
let z = 2 in
let z = z * 2 in
printfn "hi";;
samplefn();;
The important thing to understand here is that all non-top-level let bindings are actually expressions of the form let <variable> = <expression1> in <expression2> where <variable> is bound to the result of <expression1> in a new scope <expression2>, and <expression2> is the return value of the entire expression. The light syntax makes you believe such let bindings are variable assignments / statements, when in fact it really is true that almost everything in F# is an expression.
Perhaps the following illustrates this more clearly:
let a = (let b = 3 in b + 2) //a is 5
2nd Version (top-level let bindings)
let z = 2;;
let z = z * 2;;
printfn "Error: Duplicate definition of value z";;
Top level let-bindings are terminated with ;;, indicating the completion of what may be thought of as a statement. The top-level is a single scope, and here we get an error for trying to bind z twice within the same scope. Whereas using the expression form of let bindings in Example 1, we bind z anew for each sub-scope in the expression chain. Note that we could do something like this at the top-level:
let z = (let z = 2 in z * 2);;
A let that is not at the top level (e.g. your indented ones) has to have a statement (actually an expression, as pst notes) called a "body" following the assignment. In the first example the body is printfn "hi", while the second example has no body. That's what the compiler is complaining about.
Note that in your function definitions the inner let expressions actually create nested scopes. That is, the let z = z * 2 actually creates a new value called z and binds to it the value of the outer z times 2, then uses it in the body of the let (which is the printfn in this case). A nested let will always have a body. It is the nesting which allows the seemingly duplicate definition.
Since an outermost let does not need a body, the compiler thinks you're trying to redefine z in the same scope, which is an error. You can use parentheses to tell the compiler how to properly interpret the last example:
let z = 2
(let z = z * 2
printfn "z = %d" z)
printfn "z = %d" z
The above will print z = 4
z = 2

Resources