I want to bind a Variable to several atoms in such way that later it will be unifiable with one of those atoms.
Intuitively it should work like this (assuming that ; is disjunction of possible values):
?- X = (apple; pear), X = apple.
X = apple.
?- X = (apple; pear), X = apple, X = pear.
false.
?- X = (apple; pear; orange), X = (apple; orange).
X = (apple; orange).
?- X = (apple; orange), X = (pear; orange).
X = orange.
?- X = (apple; orange), X = pear.
false.
As u see this idea is close to the concept of type hierarchies.
So, I wonder is there some built in (meta-)predicates which makes easy to do such kind of things, or if there is some common way using some sort of data structure to model this, or otherwise I have to build this kind of predicates from scratch?
As you see from other answers, there is a straight-forward way to express this with Prolog, using either disjunctions (leaving choice-points), or by explicitly reasoning about sets and their intersections.
Another way is to use constraints, which let you defer goals until more is known: You can for example map your atoms to integers, and then express a variable's membership to a set as its having a specific domain of integers, using CLP(FD) constraints. Alternatively, you can implement a custom constraint solver that reasons over atoms, using attributed variables or Constraint Handling Rules (CHR). The key advantage in both cases is that you gain more freedom to reorder your goals, and the constraint reasoning is implicitly invoked when further constraints are posted.
EDIT: As an example, consider using CLP(FD) constraints to solve your task. With at most minimal modifications, the following example works in SICStus, SWI, YAP and other systems. Depending on your Prolog system, you may need to import suitable libraries to use some of these predicates:
fruit_integer(apple, 0).
fruit_integer(pear, 1).
fruit_integer(orange, 2).
variable_fruits(Var, Fruits) :-
maplist(fruit_integer, Fruits, Integers),
foldl(domain_, Integers, 1..0, D),
Var in D.
domain_(E, D0, D0 \/ E).
The key idea in this case is to map fruits to integers, so that you can use CLP(FD) constraints to express everything that holds.
Your example queries and answers::
?- variable_fruits(X, [apple,pear]), fruit_integer(apple, X).
X = 0.
?- variable_fruits(X, [apple,pear]),
fruit_integer(apple, X),
fruit_integer(pear, X).
false.
?- variable_fruits(X, [apple,pear,orange]),
variable_fruits(X, [apple,orange]).
X in 0\/2.
?- variable_fruits(X, [apple,orange]),
variable_fruits(X, [pear,orange]).
X = 2.
?- variable_fruits(X, [apple,orange]),
fruit_integer(pear, X).
false.
Obviously, you can use fruit_integer/2 also in the other direction, and convert such integers and domains back to lists of atoms. I leave this as an easy exercise.
It is for this reason that CLP(FD) constraints are called constraints over finite domains: All finite domains can be mapped to finite subsets of integers. Hence, CLP(FD) constraints are not only useful to express integer arithmetic in general, but also to reason about arbitrary finite sets. See clpfd for more information.
A few additional notes:
All most widely used Prolog systems ship with CLP(FD) constraints, making your solution quite portable if you use them.
Some Prolog systems ship with dedicated constraints solvers for sets. This may be worth looking into if your system supports this.
CHR is a useful language for defining custom propagation rules and is well worth looking into especially for more complex tasks.
Using the attributed variables interface directly will render your solution less portable, so I recommend you use one of the higher-level approaches instead. Try CLP(FD) first (since it is easiest to apply), then have a look at CHR, and only then consider implementing a custom solver.
You can just use member/2:
24 ?- member(X, [apple, pear]), member(X, [apple]).
X = apple ;
false.
25 ?- member(X, [apple, pear]), member(X, [apple]), member(X, [pear]).
false.
26 ?- member(X, [apple, pear, orange]), member(X, [apple, orange]).
X = apple ;
X = orange.
27 ?- member(X, [apple, orange]), member(X, [pear, orange]).
X = orange.
28 ?- member(X, [apple, orange]), member(X, [pear]).
false.
Or model this with lists of possible values, using intersection/3 to narrow the possibilities:
35 ?- _X1=[apple, pear], intersection(_X1, [apple], X2).
X2 = [apple].
36 ?- _X1=[apple, pear], intersection(_X1, [apple], _X2),
intersection(_X2, [pear], X3).
X3 = [].
37 ?- _X1=[apple, pear, orange], intersection(_X1, [apple, orange], X2).
X2 = [apple, orange].
38 ?- _X1=[apple, orange], intersection(_X1, [pear, orange], X2).
X2 = [orange].
39 ?- _X1=[apple, orange], intersection(_X1, [pear], X2).
X2 = [].
Maybe you're are using the wrong syntax:
?- X = apple ; X = pear.
X = apple ;
X = pear.
but I would go with the suggestion by Will Ness.
Though in my answer it was not clear how the problem is related to type hierarchy, it was triggered by the latter, and one efficient solution is given in the paper:
AN OPTIMIZED PROLOG ENCODING OF TYPED FEATURE STRUCTURES, GERALD PENN, 1999.
where the Colmerauer's method is used and simply saying:
'apple or pear' = f(0,_,1,1).
'pear or orange' = f(0,0,_,1).
'orange or apple' = f(0,X,X,1).
'apple' = f(0,1,1,1).
'orange' = f(0,0,0,1).
'pear' = f(0,0,1,1)
and all these denotations obey prolog matching:
'apple or pear' subsumes 'apple' and 'pear',
unifying 'apple or orange' with 'apple or pear' gives 'apple'.
Related
In Z3-Py, I am performing quantifier elimination (QE) over the following formulae:
Exists y. Forall x. (x>=2) => ((y>1) /\ (y<=x))
Forall x. Exists y. (x>=2) => ((y>1) /\ (y<=x)),
where both x and y are Integers. I did QE in the following way:
x, y = Ints('x, y')
t = Tactic("qe")
negS0= (x >= 2)
s1 = (y > 1)
s2 = (y <= x)
#EA
ea = Goal()
ea.add(Exists([y],Implies(negS0, (ForAll([x], And(s1,s2))))))
ea_qe = t(ea)
print(ea_qe)
#AE
ae = Goal()
ae.add(ForAll([x],Implies(negS0, (Exists([y], And(s1,s2))))))
ae_qe = t(ae)
print(ae_qe)
Result QE for ae is as expected: [[]] (i.e., True). However, as for ea, QE outputs: [[Not(x, >= 2)]], which is a results that I do not know how to interpret since (1) it has not really performed QE (note the resulting formula still contains x and indeed does not contain y which is the outermost quantified variable) and (2) I do not understand the meaning of the comma in x, >=. I cannot get the model either:
phi = Exists([y],Implies(negS0, (ForAll([x], And(s1,s2)))))
s_def = Solver()
s_def.add(phi)
print(s_def.model())
This results in the error Z3Exception: model is not available.
I think the point is as follows: since (x>=2) is an implication, there are two ways to satisfy the formula; by making the antecedent False or by satisfying the consequent. In the second case, the model would be y=2. But in the first case, the result of QE would be True, thus we cannot get a single model (as it happens with a universal model):
phi = ForAll([x],Implies(negS0, (Exists([y], And(s1,s2)))))
s_def = Solver()
s_def.add(phi)
print(s_def.model())
In any case, I cannot 'philosophically' understand the meaning of a QE of x where x is part of the (quantifier-eliminated) answer.
Any help?
There are two separate issues here, I'll address them separately.
The mysterious comma This is a common gotcha. You declared:
x, y = Ints('x, y')
That is, you gave x the name "x," and y the name "y". Note the comma after the x in the name. This should be
x, y = Ints('x y')
I guess you can see the difference: The name you gave to the variable x is "x," when you do the first; i.e., comma is part of the name. Simply skip the comma on the right hand side, which isn't what you intended anyhow. And the results will start being more meaningful. To be fair, this is a common mistake, and I wish the z3 developers ignored the commas and other punctuation in the string you give; but that's just not the case. They simply break at whitespace.
Quantification
This is another common gotcha. When you write:
ea.add(Exists([y],Implies(negS0, (ForAll([x], And(s1,s2))))))
the x that exists in negS0 is not quantified over by your ForAll, since it's not in the scope. Perhaps you meant:
ea.add(Exists([y],ForAll([x], Implies(negS0, And(s1,s2)))))
It's hard to guess what you were trying to do, but I hope the above makes it clear that the x wasn't quantified. Also, remember that a top-level exist quantifier in a formula is more or less irrelevant. It's equivalent to a top-level declaration for all practical purposes.
Once you make this fix, I think things will become more clear. If not, please ask further clarifying questions. (As a separate question on Stack-overflow; as edits to existing questions only complicate the matters.)
How to perform arithmetic with values of different widths ?
In verilog there is no problem xoring 2 bits with 8 bits but cryptol complains:
cryptol> let test(x: [2],y: [8]) = x ^ y
[error] at <interactive>:1:31--1:32:
Type mismatch:
Expected type: 2
Inferred type: 8
My original problem:
I would like to rotate the bytes in a 64 bit value, with the number of bytes to shift depending on a two bit input. I struggle to get this working:
cryptol> let shift (v, s:[2]) = v >>> (s*16+8)
[error] at <interactive>:1:5--1:38:
Unsolved constraint:
2 >= 5
arising from
use of literal or demoted expression
at <interactive>:1:33--1:35
In the interpreter I can remove the type specification of s and then it works however I need to get that working from a file and with s being really a 2 bit value.
The type of ^ is:
Cryptol> :t (^)
(^) : {a} (Logic a) => a -> a -> a
Note that it requires both arguments to be exactly the same. You're getting the type-error because [2] is not the same as [8]; as they differ in size. Unlike Verilog, Cryptol will not "pad" things implicitly, and I think Cryptol is definitely doing the right thing here. Verilog programmers can chime in with countless bugs they had due to implicit casting.
All such casting in Cryptol has to be explicit.
The typical way to deal with this situation in Cryptol is to use the polymorphic constant zero:
Cryptol> :t zero
zero : {a} (Zero a) => a
The value zero inhabits all types (you can ignore the Zero constraint for now), and as you can imagine is the "right" padding value in this case. So, you'd define your function as:
Cryptol> let test(x:[2], y:[8]) = (zero#x)^y
Cryptol> :t test
test : ([2], [8]) -> [8]
And use it like this:
Cryptol> test (1, 5)
0x04
And if you wanted to pad on the right for some reason, you'd do:
Cryptol> let test(x:[2], y:[8]) = (x#zero)^y
Cryptol> test(1,5)
0x45
This way, everything is explicit and you don't have to know all the magical rules about how things get padded to become the right size.
If you want to get real fancy, then you can do:
Cryptol> let test(x, y) = (zero#x)^(zero#y)
Cryptol> :t test
test : {n, m, i, j, a} (Logic a, Zero a, m + i == n + j, fin n,
fin m) =>
([i]a, [j]a) -> [m + i]a
Now, that type looks a bit scary; but essentially it's telling you that you can give it any sized arguments, and it would be valid for any other size, so long as the new size is larger than the maximum of the two you've given. Of course, this inferred size is way more polymorphic then you probably cared for; so you can give it something more readable:
test : {m, n} (fin m, fin n) => [m] -> [n] -> [max m n]
test x y = (zero#x) ^ (zero#y)
I believe this captures your intent perfectly. Note how cryptol will make sure your inputs are finite, and you get the maximum of the two sizes given.
Getting back to your example, Cryptol is telling you that to multiply by 16 you need at least 5 bits, and thus 2>=5 is not satisfiable. This is a bit cryptic, but arises from the use of literals which are polymorphically typed. You can use the zero trick to address the issue in the same way as before:
Cryptol> let shift (v, s:[2]) = v >>> ((zero#s)*16+8)
[warning] at <interactive>:1:32--1:38:
Defaulting type argument 'front' of '(#)' to 3
But note how cryptol is warning you about the type of zero that's used there, since the type of >>> is polymorphic enough to allow different size shifts/rotates:
Cryptol> :t (>>>)
(>>>) : {n, ix, a} (fin n, fin ix) => [n]a -> [ix] -> [n]a
In these cases, Cryptol will pick the smallest possible size to default to by looking at the expressions. Unfortunately, it does the wrong thing here. By picking size 3 for zero, you'll have a 5 bit shift, but your expression can produce the maximum value of 3*16+8=56, which requires at least 6 bits to represent. Note that Cryptol only uses the minimum size required to handle the multiplication there, and does not care about overflows! This is why it's important to pay attention to such warnings.
To be clear: Cryptol did the right thing per the language rules on how type inference works, but it ended up picking a size that is just too small for what you wanted to do.
So, you should write your shift as follows:
Cryptol> let shift (v, s:[2]) = v >>> (((zero:[4])#s)*16+8)
Cryptol> :t shift
shift : {n, a} (fin n) => ([n]a, [2]) -> [n]a
The important thing here is to make sure the expression s*16+8 will fit in the final result, and since s is only 2 bits wide the largest value will be 56 as discussed above, which needs at least 6-bits to represent. This is why I chose [4] as the size of zero.
The moral of the story here is that you should always be explicit about the sizes of your bitvectors, and Cryptol will give you the right framework to express your constraints in a polymorphic way to allow for code reuse without ambiguity, avoiding many of the pitfalls of Verilog and other similar languages.
The ctx-solver-simplify tactic only works for bool variables, so how would I deal with variables over finite domain (e.g., which tactics to use)? For example, if z can only take 3 values 0,1,2, then how to simplify Or(z==0,z==1,z==2) to true ?
Also, even for bool expressions, the tactic ctx-solver-simplify doesn't simplify completely. For example:
x,y,z = z3.Bools('x y z')
c1 = z3.And(x==True,y==True,z==True)
c2 = z3.And(x==True,y==True,z==False)
c3 = z3.And(x==True,y==False,z==True)
c4 = z3.And(x==True,y==True,z==False)
z3.Tactic('ctx-solver-simplify')(z3.Or([c1,c2,c3,c4]))
[[Or(And(x, z), And(x == True, y == True, z == False))]]
How do I get something like And(x, Or(z, y)) ?
Thanks !
Reducing Boolean (or other finite-domain) problems to a minimal form is a hard problem. The ctx-solver-simplify tactic is one of the more expensive simplifiers, but it doesn't go all the way to the provably smallest form.
Problems from other domains (e.g., enumerations like z \in {0, 1, 2}) would have to be converted to Booleans first to use this tactic, but perhaps other tactics would be better suited, and perhaps a bit-vector encoding would help too.
I have 2 formulas F1 and F2. These two formulas share most variables, except some 'temporary' (or I call them 'free') variables having different names, that are there for some reasons.
Now I want to prove F1 == F2, but prove() method of Z3 always takes into account all the variables. How can I tell prove() to ignore those 'free' variables, and focuses only on a list of variables I really care about?
I mean with all the same input to the list of my variables, if at the output time, F1 and F2 have the same value of all these variables (regardless the values of 'free' variables), then I consider them 'equivalence'
I believe this problem has been solved in other researches before, but I dont know where to look for the information.
Thanks so much.
We can use existential quantifiers to capture 'temporary'/'free' variables.
For example, in the following example, the formulas F and G are not equivalent.
x, y, z, w = Ints('x y z w')
F = And(x >= y, y >= z)
G = And(x > z - 1, w < z)
prove(F == G)
The script will produce the counterexample [z = 0, y = -1, x = 0, w = -1].
If we consider y and w as 'temporary' variables, we may try to prove:
prove(Exists([y], F) == Exists([w], G))
Now, Z3 will return proved. Z3 is essentially showing that for all x and z, there is a y that makes F true if and only if there is a w that makes G true.
Here is the full example.
Remark: when we add quantifiers, we are making the problem much harder for Z3. It may return unknown for problems containing quantifiers.
Apparently, I cannot comment, so I have to add another answer. The process of "disregarding" certain variables is typically called "projection" or "forgetting". I am not familiar with it in contexts going beyond propositional logic, but if direct existential quantification is possible (which Leo described), it is conceptually the simplest way to do it.
What is "monadic reflection"?
How can I use it in F#-program?
Is the meaning of term "reflection" there same as .NET-reflection?
Monadic reflection is essentially a grammar for describing layered monads or monad layering. In Haskell describing also means constructing monads. This is a higher level system so the code looks like functional but the result is monad composition - meaning that without actual monads (which are non-functional) there's nothing real / runnable at the end of the day. Filinski did it originally to try to bring a kind of monad emulation to Scheme but much more to explore theoretical aspects of monads.
Correction from the comment - F# has a Monad equivalent named "Computation Expressions"
Filinski's paper at POPL 2010 - no code but a lot of theory, and of course his original paper from 1994 - Representing Monads. Plus one that has some code: Monad Transformers and Modular Interpreters (1995)
Oh and for people who like code - Filinski's code is on-line. I'll list just one - go one step up and see another 7 and readme. Also just a bit of F# code which claims to be inspired by Filinski
I read through the first Google hit, some slides:
http://www.cs.ioc.ee/mpc-amast06/msfp/filinski-slides.pdf
From this, it looks like
This is not the same as .NET reflection. The name seems to refer to turning data into code (and vice-versa, with reification).
The code uses standard pure-functional operations, so implementation should be easy in F#. (once you understand it)
I have no idea if this would be useful for implementing an immutable cache for a recursive function. It look like you can define mutable operations and convert them to equivalent immutable operations automatically? I don't really understand the slides.
Oleg Kiselyov also has an article, but I didn't even try to read it. There's also a paper from Jonathan Sobel (et al). Hit number 5 is this question, so I stopped looking after that.
As previous answers links describes, Monadic reflection is a concept to bridge call/cc style and Church style programming. To describe these two concepts some more:
F# Computation expressions (=monads) are created with custom Builder type.
Don Syme has a good blog post about this. If I write code to use a builder and use syntax like:
attempt { let! n1 = f inp1
let! n2 = failIfBig inp2
let sum = n1 + n2
return sum }
the syntax is translated to call/cc "call-with-current-continuation" style program:
attempt.Delay(fun () ->
attempt.Bind(f inp1,(fun n1 ->
attempt.Bind(f inp2,(fun n2 ->
attempt.Let(n1 + n2,(fun sum ->
attempt.Return(sum))))))))
The last parameter is the next-command-to-be-executed until the end.
(Scheme-style programming.)
F# is based on OCaml.
F# has partial function application, but it also is strongly typed and has value restriction.
But OCaml don't have value restriction.
OCaml can be used in Church kind of programming, where combinator-functions are used to construct any other functions (or programs):
// S K I combinators:
let I x = x
let K x y = x
let S x y z = x z (y z)
//examples:
let seven = S (K) (K) 7
let doubleI = I I //Won't work in F#
// y-combinator to make recursion
let Y = S (K (S I I)) (S (S (K S) K) (K (S I I)))
Church numerals is a way to represent numbers with pure functions.
let zero f x = x
//same as: let zero = fun f -> fun x -> x
let succ n f x = f (n f x)
let one = succ zero
let two = succ (succ zero)
let add n1 n2 f x = n1 f (n2 f x)
let multiply n1 n2 f = n2(n1(f))
let exp n1 n2 = n2(n1)
Here, zero is a function that takes two functions as parameters: f is applied zero times so this represent the number zero, and x is used to function combination in other calculations (like add). succ function is like plusOne so one = zero |> plusOne.
To execute the functions, the last function will call the other functions with last parameter (x) as null.
(Haskell-style programming.)
In F# value restriction makes this hard. Church numerals can be made with C# 4.0 dynamic keyword (which uses .NET reflection inside). I think there are workarounds to do that also in F#.