what's the meaning of "at-most" keyword in SMT-LIB language (extended version of Z3 FixedPoint) - smt

like in this file the "at-most" keyword in the rule:
horn1.smt2(from the Z3 github repository examples/python/data)
(declare-rel Goal (Bool Bool Bool Bool Bool Bool Bool Bool Bool Bool Bool Bool))
(declare-rel Invariant (Bool Bool Bool Bool Bool Bool Bool Bool Bool Bool Bool Bool))
(declare-var A Bool)
(declare-var B Bool)
(declare-var C Bool)
(declare-var D Bool)
(declare-var E Bool)
(declare-var F Bool)
(declare-var G Bool)
(declare-var H Bool)
(declare-var I Bool)
(declare-var J Bool)
(declare-var K Bool)
(declare-var L Bool)
(declare-var M Bool)
(declare-var N Bool)
(declare-var O Bool)
(declare-var P Bool)
(declare-var Q Bool)
(declare-var R Bool)
(declare-var S Bool)
(declare-var T Bool)
(declare-var U Bool)
(declare-var V Bool)
(declare-var W Bool)
(declare-var X Bool)
(rule (=> (not (or L K J I H G F E D C B A)) (Invariant L K J I H G F E D C B A)))
(rule (let ((a!1 (and (Invariant X W V U T S R Q P O N M)
(=> (not (and true)) (not F))
(=> (not (and true)) (not E))
(=> (not (and W)) (not D))
(=> (not (and W)) (not C))
(=> (not (and U)) (not B))
(=> (not (and U)) (not A))
(= L (xor F X))
(= K (xor E W))
(= J (xor D V))
(= I (xor C U))
(= H (xor B T))
(= G (xor A S))
(=> D (not E))
(=> C (not E))
(=> B (not C))
(=> A (not C))
((_ at-most 5) L K J I H G))))
(=> a!1 (Invariant L K J I H G F E D C B A))))
(rule (=> (and (Invariant L K J I H G F E D C B A) L (not K) J (not I) H G)
(Goal L K J I H G F E D C B A)))
(query Goal)
It seems like the meaning of the keyword "at-most" is that only five literal of the six literal (L K J I H G) can be true simultaneously, or it means anything else, I can't figure it out. I really appreciate it if there's any nice guy could help me out.

These are pseudo-boolean functions, see this answer for details: K-out-of-N constraint in Z3Py
Basically:
at-most: At most this many are true
at-least: At least this many are true
pble: At most this many, weighted
pbge: At least this many, weighted
pbeq: Exactly this many, weighted
The weighted versions are essentially multipliers on the boolean, and take a constant list of integers.
Note that these are z3 specific, and not actually defined in SMTLib. There might be other solvers that support it too, of course.

Related

Haskell correct types for class and instance

I am struggling to describe what it means for terms and literals (first order logic) to be re-written. Ie I would like a function applySubstitution that can be called on both terms and literals.
I thought that the substitution could be expressed as a function. However I am getting rigid type variable errors with the following code.
{-# LANGUAGE UnicodeSyntax #-}
module Miniexample where
import qualified Data.Maybe as M
data Term a = F a [Term a]
| V a
data Literal a = P a [Term a]
| E (Term a) (Term a)
class Substitutable b where
substitute :: b -> (Term a -> Maybe (Term a)) -> b
instance Substitutable (Term a) where
substitute x#(V _) σ = M.fromMaybe x (σ x)
substitute f#(F l xs) σ = M.fromMaybe f' (σ f)
where f' = F l (map (flip substitute σ) xs)
instance Substitutable (Literal a) where
substitute (P l xs) σ = P l (map (flip substitute σ) xs)
substitute (E s t) σ = E (substitute s σ) (substitute t σ)
class Substitution σ where
asSub :: σ -> (a -> Maybe a)
applySubstitution σ t = substitute t (asSub σ)
(<|) t σ = applySubstitution σ t
This gives be the following error:
• Couldn't match type ‘a1’ with ‘a’
‘a1’ is a rigid type variable bound by
the type signature for:
substitute :: forall a1.
Term a -> (Term a1 -> Maybe (Term a1)) -> Term a
at /.../Miniexample.hs:16:3-12
‘a’ is a rigid type variable bound by
the instance declaration
at /.../Miniexample.hs:15:10-31
Expected type: Term a1
Actual type: Term a
• In the first argument of ‘σ’, namely ‘x’
In the second argument of ‘M.fromMaybe’, namely ‘(σ x)’
In the expression: M.fromMaybe x (σ x)
• Relevant bindings include
σ :: Term a1 -> Maybe (Term a1)
(bound at /.../Miniexample.hs:16:22)
x :: Term a
(bound at /.../Miniexample.hs:16:14)
substitute :: Term a -> (Term a1 -> Maybe (Term a1)) -> Term a
(bound at /.../Miniexample.hs:16:3)
In my head, the type variable b in the Substitutable class should be able to take on (bad terminology I'm sure) the the value of Term a.
Any hints would be greatly welcome.
To give a more concrete example, the following works, but one needs to be explicit about which function applyTermSub or applyLitSub to call and secondly the implementation of the substitution map leaks into the implementation of the more general procedure.
module Miniexample where
import qualified Data.Maybe as M
import qualified Data.List as L
data Term a = F a [Term a]
| V a deriving (Eq)
data Literal a = P a [Term a]
| E (Term a) (Term a) deriving (Eq)
termSubstitute :: (Term a -> Maybe (Term a)) -> Term a -> Term a
termSubstitute σ x#(V _) = M.fromMaybe x (σ x)
termSubstitute σ f#(F l xs) = M.fromMaybe f' (σ f)
where f' = F l (map (termSubstitute σ) xs)
litSubstitute :: (Term a -> Maybe (Term a)) -> Literal a -> Literal a
litSubstitute σ (P l xs) = P l (map (termSubstitute σ) xs)
litSubstitute σ (E s t) = E (termSubstitute σ s) (termSubstitute σ t)
applyTermSub :: (Eq a) => Term a -> [(Term a, Term a)] -> Term a
applyTermSub t σ = termSubstitute (flip L.lookup σ) t
applyLitSub :: (Eq a) => Literal a -> [(Term a, Term a)] -> Literal a
applyLitSub l σ = litSubstitute (flip L.lookup σ) l
-- variables
x = V "x"
y = V "y"
-- constants
a = F "a" []
b = F "b" []
-- functions
fa = F "f" [a]
fx = F "f" [x]
σ = [(x,y), (fx, fa)]
test = (applyLitSub (P "p" [x, b, fx]) σ) == (P "p" [y, b, fa])
Ideally I would like to have an interface for substitutions (i.e one could use Data.Map etc) and secondly I would like a single substitute function that captures both term and literals.
The error you're getting is a complaint that Term a, as specified in instance Substitutable (Term a), is not the same type as the Term a that σ accepts. This is because Haskell quantifies a over the substitute function, but not over the rest of the instance definition. So an implementation of substitute must accept a σ that handles Term a1 for some value of a1, which is not guaranteed to be the specific a that your instance is defined on. (Yes, your instance is defined over all a... but from inside the scope of the instance definition, it's as if a specific a has been chosen.)
You can avoid this by parameterizing your Substitutable class by a type constructor instead of just a type, and passing the same a to that type constructor as is used in the σ type.
{-# LANGUAGE UnicodeSyntax #-}
import qualified Data.Maybe as M
import qualified Data.List as L
data Term a = F a [Term a]
| V a deriving (Eq)
data Literal a = P a [Term a]
| E (Term a) (Term a) deriving (Eq)
class Substitutable f where
substitute :: f a -> (Term a -> Maybe (Term a)) -> f a
instance Substitutable Term where
substitute x#(V _) σ = M.fromMaybe x (σ x)
substitute f#(F l xs) σ = M.fromMaybe f' (σ f)
where f' = F l (map (flip substitute σ) xs)
instance Substitutable Literal where
substitute (P l xs) σ = P l (map (flip substitute σ) xs)
substitute (E s t) σ = E (substitute s σ) (substitute t σ)
(<|) t σ = substitute t $ flip L.lookup σ
-- variables
x = V "x"
y = V "y"
-- constants
a = F "a" []
b = F "b" []
-- functions
fa = F "f" [a]
fx = F "f" [x]
σ = [(x,y), (fx, fa)]
main = print $ show $ (P "p" [x, b, fx] <| σ) == P "p" [y, b, fa]

Remove from list from other list

I have list witch contain other lists (2 levels only)
((S U S U R) (S U S R) (S U R))
How to remove the lists from list which contains some pairs, the same combination of 2 element on first ans second position in list or 3th and 4th position (in my example "S U") and to return ((S U S R) (S U R))
I need to transform
((S U S U R) (S U S R) (S U R)) to => ((S U S R) (S U R))
((S U R S U) (S U S R) (S U R)) to => ((S U R S U) (S U S R) (S U R)) - do not change, because here is pairs have S U, R S, U and no S U 2 or more times
REMOVE-IF
(remove-if #'oddp '(1 2 3 4 5))
=> (2 4)
LAMBDA
(funcall (lambda (x) (string x)) :example)
=> "EXAMPLE"
EQUALP
(equalp '(S U) (list 's 'u))
=> T
SUBSEQ
(subseq '(a b c d) 0 3)
=> (A B C)
Careful:
(subseq '(a b c d) 0 10)
=> ERROR
You can also use LENGTH to get the size of a list. You could also use following functions...
NTHCDR
(nthcdr '(s u s u r u) 5)
=> (U)
LDIFF
(let ((list '(a b c d)))
(ldiff list (nthcdr 10 list)))
=> (A B C D)
(let ((list '(a b c d)))
(ldiff list (nthcdr 2 list)))
=> (A B)
What you want to do
You want to remove elements from the input list that satisfy the following predicate: given a list, a subset of this list is equal to (S U) (see comments).
Your code will looks like this:
(defun remove-s-u-at-pos-3 (list)
(remove-if (lambda (...) ...) list))
You need to extract a part of each visited list and compare it to (S U).

Rank-2 types in data constructors

I've been trying to encode GADTs in PureScript using rank-2 types, as described here for Haskell
My code looks like:
data Z
data S n
data List a n
= Nil (Z -> n)
| Cons forall m. a (List a m) (S m -> n)
fw :: forall f a. (Functor f) => (forall b . (a -> b) -> f b) -> f a
fw f = f id
bw :: forall f a. (Functor f) => f a -> (forall b . (a -> b) -> f b)
bw x f = map f x
nil :: forall a. List a Z
nil = fw Nil
cons :: forall a n. a -> List a (S n)
cons a as = fw (Cons a as)
instance listFunctor :: Functor (List a) where
map f (Nil k) = Nil (f <<< k)
map f (Cons x xs k) = Cons x xs (f <<< k)
The compiler complains Wrong number of arguments to constructor Main.Cons, referring to the LHS pattern match in the Functor instance.
What is going wrong here?
Regards,
Michael
The syntax used for existential types in Haskell is not present in PureScript. What you've written for Cons is a data constructor with a single universally-quantified argument.
You might like to try using purescript-exists to encode the existential type instead.
Another option is to use a final-tagless encoding of the GADT:
class Listy l where
nil :: forall a. l Z a
cons :: forall a n. a -> l n a -> l (S n) a
You can write terms for any valid Listy instance:
myList :: forall l. (Listy l) => l (S (S Z)) Int
myList = cons 1 (cons 2 nil)
and interpret them by writing instances
newtype Length n a = Length Int
instance lengthListy :: Listy Length where
nil = Length 0
cons _ (Length n) = Length (n + 1)
newtype AsList n a = AsList (List a)
instance asListListy :: Listy AsList where
nil = AsList Nil
cons x (AsList xs) = AsList (Cons x xs)

Extracting a constraint from a conjunction

Here's a tree of Boolean predicates.
data Pred a = Leaf (a -> Bool)
| And (Pred a) (Pred a)
| Or (Pred a) (Pred a)
| Not (Pred a)
eval :: Pred a -> a -> Bool
eval (Leaf f) = f
eval (l `And` r) = \x -> eval l x && eval r x
eval (l `Or` r) = \x -> eval l x || eval r x
eval (Not p) = not . eval p
This implementation is simple, but the problem is that predicates of different types don't compose. A toy example for a blogging system:
data User = U {
isActive :: Bool
}
data Post = P {
isPublic :: Bool
}
userIsActive :: Pred User
userIsActive = Leaf isActive
postIsPublic :: Pred Post
postIsPublic = Leaf isPublic
-- doesn't compile because And requires predicates on the same type
-- userCanComment = userIsActive `And` postIsPublic
You could get around this by defining something like data World = W User Post, and exclusively using Pred World. However, adding a new entity to your system then necessitates changing World; and smaller predicates generally don't require the whole thing (postIsPublic doesn't need to use the User); client code that's in a context without a Post lying around can't use a Pred World.
It works a charm in Scala, which will happily infer subtype constraints of composed traits by unification:
sealed trait Pred[-A]
case class Leaf[A](f : A => Boolean) extends Pred[A]
case class And[A](l : Pred[A], r : Pred[A]) extends Pred[A]
case class Or[A](l : Pred[A], r : Pred[A]) extends Pred[A]
case class Not[A](p : Pred[A]) extends Pred[A]
def eval[A](p : Pred[A], x : A) : Boolean = {
p match {
case Leaf(f) => f(x)
case And(l, r) => eval(l, x) && eval(r, x)
case Or(l, r) => eval(l, x) || eval(r, x)
case Not(pred) => ! eval(pred, x)
}
}
class User(val isActive : Boolean)
class Post(val isPublic : Boolean)
trait HasUser {
val user : User
}
trait HasPost {
val post : Post
}
val userIsActive = Leaf[HasUser](x => x.user.isActive)
val postIsPublic = Leaf[HasPost](x => x.post.isPublic)
val userCanCommentOnPost = And(userIsActive, postIsPublic) // type is inferred as And[HasUser with HasPost]
(This works because Pred is declared as contravariant - which it is anyway.) When you need to eval a Pred, you can simply compose the required traits into an anonymous subclass - new HasUser with HasPost { val user = new User(true); val post = new Post(false); }
I figured I could translate this into Haskell by turning the traits into classes and parameterising Pred by the type classes it requires, rather than the concrete type it operates on.
-- conjunction of partially-applied constraints
-- (/\) :: (k -> Constraint) -> (k -> Constraint) -> (k -> Constraint)
type family (/\) c1 c2 a :: Constraint where
(/\) c1 c2 a = (c1 a, c2 a)
data Pred c where
Leaf :: (forall a. c a => a -> Bool) -> Pred c
And :: Pred c1 -> Pred c2 -> Pred (c1 /\ c2)
Or :: Pred c1 -> Pred c2 -> Pred (c1 /\ c2)
Not :: Pred c -> Pred c
data User = U {
isActive :: Bool
}
data Post = P {
isPublic :: Bool
}
class HasUser a where
user :: a -> User
class HasPost a where
post :: a -> Post
userIsActive :: Pred HasUser
userIsActive = Leaf (isActive . user)
postIsPublic :: Pred HasPost
postIsPublic = Leaf (isPublic . post)
userCanComment = userIsActive `And` postIsPublic
-- ghci> :t userCanComment
-- userCanComment :: Pred (HasUser /\ HasPost)
The idea is that each time you use Leaf you define a requirement (such as HasUser) on the type of the whole without specifying that type directly. The other constructors of the tree bubble those requirements upwards (using constraint conjuction /\), so the root of the tree knows about all of the requirements of the leaves. Then, when you want to eval your predicate, you can make up a type containing all the data the predicate needs (or use tuples) and make it an instance of the required classes.
However, I can't figure out how to write eval:
eval :: c a => Pred c -> a -> Bool
eval (Leaf f) = f
eval (l `And` r) = \x -> eval l x && eval r x
eval (l `Or` r) = \x -> eval l x || eval r x
eval (Not p) = not . eval p
It's the And and Or cases that go wrong. GHC seems unwilling to expand /\ in the recursive calls:
Could not deduce (c1 a) arising from a use of ‘eval’
from the context (c a)
bound by the type signature for
eval :: (c a) => Pred c -> a -> Bool
at spec.hs:55:9-34
or from (c ~ (c1 /\ c2))
bound by a pattern with constructor
And :: forall (c1 :: * -> Constraint) (c2 :: * -> Constraint).
Pred c1 -> Pred c2 -> Pred (c1 /\ c2),
in an equation for ‘eval’
at spec.hs:57:7-15
Relevant bindings include
x :: a (bound at spec.hs:57:21)
l :: Pred c1 (bound at spec.hs:57:7)
eval :: Pred c -> a -> Bool (bound at spec.hs:56:1)
In the first argument of ‘(&&)’, namely ‘eval l x’
In the expression: eval l x && eval r x
In the expression: \ x -> eval l x && eval r x
GHC knows c a and c ~ (c1 /\ c2) (and therefore (c1 /\ c2) a) but can't deduce c1 a, which would require expanding the definition of /\. I have a feeling it would work if /\ were a type synonym, not a family, but Haskell doesn't permit partial application of type synonyms (which is required in the definition of Pred).
I attempted to patch it up using constraints:
conjL :: (c1 /\ c2) a :- c1 a
conjL = Sub Dict
conjR :: (c1 /\ c2) a :- c1 a
conjR = Sub Dict
eval :: c a => Pred c -> a -> Bool
eval (Leaf f) = f
eval (l `And` r) = \x -> (eval l x \\ conjL) && (eval r x \\ conjR)
eval (l `Or` r) = \x -> (eval l x \\ conjL) || (eval r x \\ conjR)
eval (Not p) = not . eval p
Not only...
Could not deduce (c3 a) arising from a use of ‘eval’
from the context (c a)
bound by the type signature for
eval :: (c a) => Pred c -> a -> Bool
at spec.hs:57:9-34
or from (c ~ (c3 /\ c4))
bound by a pattern with constructor
And :: forall (c1 :: * -> Constraint) (c2 :: * -> Constraint).
Pred c1 -> Pred c2 -> Pred (c1 /\ c2),
in an equation for ‘eval’
at spec.hs:59:7-15
or from (c10 a0)
bound by a type expected by the context: (c10 a0) => Bool
at spec.hs:59:27-43
Relevant bindings include
x :: a (bound at spec.hs:59:21)
l :: Pred c3 (bound at spec.hs:59:7)
eval :: Pred c -> a -> Bool (bound at spec.hs:58:1)
In the first argument of ‘(\\)’, namely ‘eval l x’
In the first argument of ‘(&&)’, namely ‘(eval l x \\ conjL)’
In the expression: (eval l x \\ conjL) && (eval r x \\ conjR)
but also...
Could not deduce (c10 a0, c20 a0) arising from a use of ‘\\’
from the context (c a)
bound by the type signature for
eval :: (c a) => Pred c -> a -> Bool
at spec.hs:57:9-34
or from (c ~ (c3 /\ c4))
bound by a pattern with constructor
And :: forall (c1 :: * -> Constraint) (c2 :: * -> Constraint).
Pred c1 -> Pred c2 -> Pred (c1 /\ c2),
in an equation for ‘eval’
at spec.hs:59:7-15
In the first argument of ‘(&&)’, namely ‘(eval l x \\ conjL)’
In the expression: (eval l x \\ conjL) && (eval r x \\ conjR)
In the expression:
\ x -> (eval l x \\ conjL) && (eval r x \\ conjR)
It's more or less the same story, except now GHC also seems unwilling to unify the variables brought in by the GADT with those required by conjL. It looks like this time the /\ in the type of conjL has been expanded to (c10 a0, c20 a0). (I think this is because /\ appears fully-applied in conjL, not in curried form as it does in And.)
Needless to say, it's surprising to me that Scala does this better than Haskell. How can I fiddle with the body of eval until it typechecks? Can I cajole GHC into expanding /\? Am I going about it the wrong way? Is what I want even possible?
The data constructors And :: Pred c1 -> Pred c2 -> Pred (c1 /\ c2) and Or :: ... are not well formed because type families cannot be partially applied. However, GHC earlier than 7.10 will erroneously accept this definition - then give the errors you see when you try to do anything with it.
You should use a class instead of a type family; for example
class (c1 a, c2 a) => (/\) (c1 :: k -> Constraint) (c2 :: k -> Constraint) (a :: k)
instance (c1 a, c2 a) => (c1 /\ c2) a
and the straightforward implementation of eval will work.

Surprising behaviour when trying to prove a forall

Consider the following SMT-LIB code:
(set-option :auto_config false)
(set-option :smt.mbqi false)
; (set-option :smt.case_split 3)
(set-option :smt.qi.profile true)
(declare-const x Int)
(declare-fun trigF (Int Int Int) Bool)
(declare-fun trigF$ (Int Int Int) Bool)
(declare-fun trigG (Int) Bool)
(declare-fun trigG$ (Int) Bool)
; Essentially noise
(declare-const y Int)
(assert (!
(not (= x y))
:named foo
))
; Essentially noise
(assert (forall ((x Int) (y Int) (z Int)) (!
(= (trigF$ x y z) (trigF x y z))
:pattern ((trigF x y z))
:qid |limited-F|
)))
; Essentially noise
(assert (forall ((x Int)) (!
(= (trigG$ x) (trigG x))
:pattern ((trigG x))
:qid |limited-G|
)))
; This assumption is relevant
(assert (forall ((a Int) (b Int) (c Int)) (!
(and
(trigG a)
(trigF a b c))
:pattern ((trigF a b c))
:qid |bar|
)))
Trying to assert that axiom bar holds, i.e.,
(push)
(assert (not (forall ((a Int) (b Int) (c Int))
(and
(trigG a)
(trigF a b c)))))
(check-sat)
(pop)
fails (Z3 4.3.2 - build hashcode 47ac5c06333b):
unknown
[quantifier_instances] limited-G : 1 : 0 : 1
Question 1: Why did Z3 only instantiate limited-G but neither limited-F nor bar (which would prove the assertion)?
Question 2: Commenting any of the (useless) assertions foo, limited-F or limited-G allows Z3 to prove the assertion - why is that? (Depending on which are commented, either only bar or bar and limited-F are instantiated.)
In case it is related to the observed behaviour: I would like to set smt.case_split to 3 (my configuration follows the one omitted by MSR's Boogie tool), but Z3 gives me WARNING: auto configuration (option AUTO_CONFIG) must be disabled to use option CASE_SPLIT=3, 4 or 5, despite the fact that (set-option :auto_config false).
The situation is as follows:
when using pattern based instantiation exclusively Z3 takes a somewhat operational approach to finding quantifier instantiations.
by disabling MBQI you rely on the equality matching engine.
case_split = 3 instructs Z3 to use relevancy heuristic when
choosing candidates for equality matching.
The assert (not (forall (a, b, c) (and (trigG a) (trigF a b c)))) expands
into a disjunction (or (not (trigG a!0)) (not (trigF a!0 b!1 c!2))).
only one of the two disjuncts is relevant for satisfying the formula.
The search sets (trigG a!0) to false, so the clause is satisfied. The trigger (trigF a b c) is therefore never activated.
You can bypass this issue by distributing in universal quantifiers over conjunctions, and supplying patterns in each case. Thus, you(r tool) could rewrite the axiom:
(assert (forall ((a Int) (b Int) (c Int)) (!
(and
(trigG a)
(trigF a b c))
:pattern ((trigF a b c))
:qid |bar|
)))
to the two axioms.
(assert (forall ((a Int)) (! (trigG a) :pattern ((trigG a))))
(assert (forall ((a Int) (b Int) (c Int)) (!
(trigF a b c)
:pattern ((trigF a b c))
:qid |bar|
)))
The issue of setting auto-completion seems fixed. I somewhat recently fixed bug in the way that some top-level configurations were reset if multiple top-level configurations were set in the smt-lib input.