Surprising behaviour when trying to prove a forall - triggers

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.

Related

assertions on inductive data types in CVC4

I am trying experiment with CVC4 a bit.
(set-option :produce-models true)
(set-option :produce-assignments true)
(set-logic QF_UFDT)
(declare-datatypes ()
(Color (Red) (Black))
)
(declare-const x C)
(declare-const y C)
(assert (not (= x y)))
(check-sat)
(get-value (x y))
(assert (distinct x y))
(check-sat)
(get-value (x y))
When I run this using CVC4 I am getting the following output
sat
((x R) (y R))
sat
((x R) (y R))
I am confused by this behaviour by this output.
If I am asserting x and y should not be equal their values must be different right?
Same is the case with distinct assertion.
Is CVC4 treating x and y as two different "objects" and hence giving the output it is giving?
I don't see the same results. This is the message I get with the latest development version of CVC4 (http://cvc4.cs.stanford.edu/downloads/):
(error "Parse Error: stack.smt2:5.8: Sequence terminated early by token: 'Color'.
(Color (Red) (Black))
^
")
There are a few syntax errors in your example, here is a corrected version:
(set-option :produce-models true)
(set-option :produce-assignments true)
(set-logic QF_UFDT)
(declare-datatypes () (
(Color (Red) (Black))
))
(declare-const x Color)
(declare-const y Color)
(assert (not (= x y)))
(check-sat)
(get-value (x y))
(assert (distinct x y))
(check-sat)
(get-value (x y))
On this input, cvc4 with the option "--incremental" (which enables multiple queries), gives this response:
sat
((x Red) (y Black))
sat
((x Red) (y Black))
Hope this helps,
Andy

Occurrence typing with polymorphic union types

Suppose I want to convert the following untyped code into typed racket. These functions are inspired by SICP where they show how a data structure can be constructed purely from functions.
(define (make-pair x y)
(lambda (c)
(cond
((= c 1) x)
((= c 2) y)
(error "error in input, should be 1 or 2"))))
(define (first p) (p 1))
(define (second p) (p 2))
To convert it straight to typed racket, the return value of the make-pair function seems to be (: make-pair (All (A B) (-> A B (-> Number (U A B))))). And following this, the type of first should be (: first (All (A B) (-> (-> Number (U A B)) A))). However, while implementing the function we can't call (p 1) directly now because we need some sort of occurrence typing to make sure first returns only of type A. Changing the return type of first to (U A B) works but then the burden of occurrence typing goes on the user and not in the API. So in this scenario how can we use occurrence typing inside first (that is, how to use a predicate for type variable A) so that we can safely return only the first component of the pair?
UPDATE
I tried an approach which differs a bit from above and requires the predicates for A and B to be supplied as arguments to make-pair function. Below is the code:
#lang typed/racket
(define-type FuncPair (All (A B) (List (-> Number (U A B)) (-> A Boolean) (-> B Boolean))))
(: make-pair (All (A B) (-> A B (-> A Boolean) (-> B Boolean) (FuncPair A B))))
(define (make-pair x y x-pred y-pred)
(list
(lambda ([c : Number])
(cond
((= c 1) x)
((= c 2) y)
(else (error "Wrong input!"))))
x-pred
y-pred))
(: first (All (A B) (-> (FuncPair A B) Any)))
(define (first p)
(let ([pair-fn (car p)]
[fn-pred (cadr p)])
(let ([f-value (pair-fn 1)])
(if (fn-pred f-value)
f-value
(error "Cannot get first value in pair")))))
However, this fails in the check (fn-pred f-value) condition with error expected: A
given: (U A B) in: f-value
From the untyped code at the start of your question, it seems like a pair of A and B is a function that given 1, gives back A, and given 2, gives back B. The way to express this type of function is with a case-> type:
#lang typed/racket
(define-type (Pairof A B)
(case-> [1 -> A] [2 -> B]))
The accessors can be defined the same way as your original untyped code, just by adding type annotations:
(: first : (All (A B) [(Pairof A B) -> A]))
(define (first p) (p 1))
(: second : (All (A B) [(Pairof A B) -> B]))
(define (second p) (p (ann 2 : 2)))
The type of the constructor should be:
(: make-pair : (All (A B) [A B -> (Pairof A B)]))
But the constructor doesn't quite work as-is. One thing wrong with it is that your else clause is missing the else part of it. Fixing that gives you:
(: make-pair : (All (A B) [A B -> (Pairof A B)]))
(define (make-pair x y)
(lambda (c)
(cond
[(= c 1) x]
[(= c 2) y]
[else (error "error in input, should be 1 or 2")])))
This is almost right, and if typed racket were awesome enough, it would be. Typed racket treats equal? specially for occurrence typing, but it doesn't do the same thing for =. Changing = to equal? fixes it.
(: make-pair : (All (A B) [A B -> (Pairof A B)]))
(define (make-pair x y)
(lambda (c)
(cond
[(equal? c 1) x]
[(equal? c 2) y]
[else (error "error in input, should be 1 or 2")])))
Ideally occurrence typing should work with =, but perhaps the fact that things like (= 2 2.0) return true makes that both harder to implement and less useful.

Sublist in common lisp

I have list of lists in my program
for example
(( a b) (c d) (x y) (d u) ........)
Actually I want to add 1 new element in the list but new element would be a parent of all existing sublists.
for example if a new element is z, so my list should become like this
( (z( a b) (c d) (x y) (d u) ........))
I have tried with push new element but it list comes like this
( z( a b) (c d) (x y) (d u) ........)
that I dont want as I have lot of new elements coming in and each element represents some block of sublists in the list
Your help would highly be appreciated.
It sounds like you just need to wrap the result of push, cons, or list* in another list:
(defun add-parent (children parent)
(list (list* parent children)))
(add-parent '((a b) (c d) (x y) (d u)) 'z)
;;=> ((Z (A B) (C D) (X Y) (D U)))
This is the approach that I'd probably take with this. It's just important that you save the return value. In this regard, it's sort of like the sort function.
However, if you want to make a destructive macro out of that, you can do that too using define-modify-macro. In the following, we use define-modify-macro to define a macro add-parentf that updates its first argument to be the result of calling add-parent (defined above) with the first argument and the parent.
(define-modify-macro add-parentf (parent) add-parent)
(let ((kids (copy-tree '((a b) (c d) (x y) (d u)))))
(add-parentf kids 'z)
kids)
;;=> ((Z (A B) (C D) (X Y) (D U)))
For such a simple case you can also use a shorter backquote approach, for example:
(let ((parent 'z) (children '((a b) (c d) (e f))))
`((,parent ,#children)))
If you aren't familiar with backquote, I'd recommend reading the nice and concise description in Appendix D: Read Macros of Paul Graham's ANSI Common Lisp.

is this function tail recursive?

in racket, i define the following function and am wondering whether it is tail recursive:
(define foo
(λ (c m s1 s2)
(if (< c m)
(if (= (modulo m c) 0)
(foo (+ c 1) m (+ s1 c) s2)
(foo (+ c 2) m s1 (+ s2 c)))
(cons s1 s2))))
my question is virtually like this, but i have to write something else to satisfy my post quality standards. actually, i do not know what is my post quality standards.
This is practically the same as your previous question. Yes, this is tail recursive: whenever a recursive call occurs in your function foo, it's in a tail position. Meaning: after the recursive call is performed, there's nothing else to do, that branch of execution ends. And the (cons s1 s2) part is the base case of the recursion, so it doesn't count. To see it more clearly, the foo procedure is equivalent to this:
(define (foo c m s1 s2)
(cond ((>= c m)
(cons s1 s2)) ; base case of recursion
((= (modulo m c) 0)
(foo (+ c 1) m (+ s1 c) s2)) ; recursive call is in tail position
(else
(foo (+ c 2) m s1 (+ s2 c))))) ; recursive call is in tail position
Let's see an example of when something is not a tail recursion. For instance, if the consequent part of the second if were defined like this:
(+ 1 (foo (+ c 1) m (+ s1 c) s2))
Then clearly the recursive call would not be in a tail position, because after the recursion returns an operation is performed: adding one to the result of the recursion.
Here's a pseudocode (Common Lisp actually) translation of your code to frame-mutating version:
(defun foo (c m s1 s2)
(prog
((c c) (m m) (s1 s1) (s2 s2)) ; the frame
BACK
(if (< c m)
(if (= (modulo m c) 0)
(progn
(psetf s1 (+ s1 c) ; set!
c (+ c 1)) ; in parallel
(go BACK))
(progn
(psetf s2 (+ s2 c) ; set!
c (+ c 2)) ; in parallel
(go BACK)))
(return-from foo (cons s1 s2))))))
Since there's nothing more left to do after each tail call, we can just (go BACK).
The only calls to foo are in the tail position, so that function looks tail recursive to me.
Section 11.20, page 59 of Scheme R6RS describes tail calls and shows the tail call position for the fundamental Scheme syntactic forms, like for if and lambda
Your calls to foo within foo are in tail position. (Because they are in the inner if tail position, the outer if tail position and the lambda tail position.)

fixed point combinator in lisp

;; compute the max of a list of integers
(define Y
(lambda (w)
((lambda (f)
(f f))
(lambda (f)
(w (lambda (x)
((f f) x)))))))
((Y
(lambda (max)
(lambda (l)
(cond ((null? l) -1)
((> (car l) (max (cdr l))) (car l))
(else (max (cdr l)))))))
'(1 2 3 4 5))
I wish to understand this construction. Can somebody give a clear and simple explanation for this code?
For example, supposing that I forget the formula of Y. How can I remember it , and reproduce it long after I work with it ?
Here's some related answers (by me):
Y combinator discussion in "The Little Schemer"
Unable to get implementation of Y combinator working
In Scheme, how do you use lambda to create a recursive function?
Basically, with Y defined as λr.(λh.h h) (λg.r (λx.(g g) x)), an application Y r reduces as
Y r
(λw.(λh.h h) (λg.w (λx.(g g) x))) r
(λh.h h) (λg.r (λx.(g g) x))
h h
;where
h = (λg.r (λx.(g g) x)) <----\
|
(λg.r (λx.(g g) x)) h |
r (λx.(g g) x) <-------------- | ----------\
;where | |
g = h -----/ |
;so that |
(g g) = (h h) = r (λx.(g g) x) ------/
So r must expect two arguments - first representing the recursive function to be called, and second - an actual argument:
r = λf (λx. ....x.....(f y)...... )
so that (Y r) x reduces as
(r (λx.(g g) x)) x
(r f) x
;where
f = (λx.(g g) x)
f y = (λx.(g g) x) y = (g g) y = (r f) y ; f is "fixed point" of r
The definiton f = (λx.(g g) x) means, when f y is called, (g g) y will be called, at which point g will be self-applied, r "pulled" from inside g and the result of (r f) called with y argument. I.e. any call (f y) in the body of lambda expression resulting from (r f) application, is translated back to (r f) y i.e. invocation of same body with a new argument y.
The important implementational detail is whether it is the same function body, or its copy, but the semantics are the same - we are able to enter the same function body with a new argument value.
The essence of Y combinator is replication through reference and self-application: we refer to the same thing through same name, twice; and thus we arrange for it to receive itself as an argument.
When there's no referencing, as in pure lambda calculus, and parameters receive textual copies of arguments - i.e. reduction is done by textual rewriting - this still works, because same copies get replicated and passed around, being fed as argument to self so it is available on the next iteration, if need be.
But it is much more efficient when shared referencing is available (all uses of same name refer to same thing). Under environment model of evaluation creation of self-referential function is simple as
(let ((fact #f))
(set! fact
(lambda (n) (if (< 2 n) 1
(* n (fact (- n 1))))))
fact)
In fact the definition in your answer is that of applicative-order Y combinator. With normal-order, eta-reduction can be applied without causing infinite looping, to get Ynorm = (λw.(λh.h h) (λg.w (g g))) which is canonically written as
Ynorm = (λf.(λx.f (x x)) (λx.f (x x)))
indeed
Ynorm g
= (λx.g (x x)) (λx.g (x x))
= g ((λx.g (x x)) (λx.g (x x)))