Encoding let-expressions in Z3 - record

The following code encodes a "record" with two fields array-fld and blist-fld. I've defined the update functions for these fields, and then asserted a property that should be true (but which z3 reports as unknown). This is Z3 version 4.0, run as z3 -smt2 -in:
(declare-datatypes ()
((mystruct (mk-mystruct
(array-fld (Array Int Int))
(blist-fld (List Bool))))))
(define-fun array-fld-upd ((v (Array Int Int)) (obj mystruct)) mystruct
(mk-mystruct v (blist-fld obj)))
(define-fun blist-fld-upd ((v (List Bool)) (obj mystruct)) mystruct
(mk-mystruct (array-fld obj) v))
(push)
(assert
(forall ((z0 mystruct))
(exists ((array-val (Array Int Int)))
(and (= array-val (array-fld z0))
(= (select (array-fld
(array-fld-upd (store array-val 2 4) z0)) 3)
(select (array-fld z0) 3))))))
(check-sat)
If I manually unwind/eliminate the existential by substituting out the equation array-val binding, I get
(pop)
(assert
(forall ((z0 mystruct))
(= (select (array-fld (array-fld-upd (store (array-fld z0) 2 4) z0)) 3)
(select (array-fld z0) 3))))
(check-sat)
and this is happily resolved as sat.
I guess there are four questions bound up in this:
Is there a way to invoke z3 to get it to solve the first instance as well as the second?
Should I be encoding my records/structs differently?
Should I be encoding my let-expressions differently (it is these that lead to the existential quantification)?
Or, should I just expand out the let-expressions directly (I could do this myself, but it might lead to large terms if there are lots of references).

It seems from the question that you can use proper let expressions.
Then it will be easier for Z3:
(declare-datatypes ()
((mystruct (mk-mystruct
(array-fld (Array Int Int))
(blist-fld (List Bool))))))
(define-fun array-fld-upd ((v (Array Int Int)) (obj mystruct)) mystruct
(mk-mystruct v (blist-fld obj)))
(define-fun blist-fld-upd ((v (List Bool)) (obj mystruct)) mystruct
(mk-mystruct (array-fld obj) v))
(push)
(assert
(forall ((z0 mystruct))
(let ((array-val (array-fld z0)))
(= (select (array-fld
(array-fld-upd (store array-val 2 4) z0)) 3)
(select (array-fld z0) 3)))))
(check-sat)

Related

Cond interpreter Scheme

I would like to write an interpreter for if and cond statements in scheme, however I couldnt do cond part.My cond has else part always.
<cond -> ( cond <conditional_list> <else_condition> )
<conditional_list -> <conditional | <conditional <conditional_list
<conditional -> ( <expr <expr )
<else_condition -> ( else <expr )
Here is my if part :
((if-stmt? e)
(if (not (eq? (my_interpreter (cadr e) env) 0))
( my_interpreter (caddr e) env)
( my_interpreter (cadddr e) env)))
Any help is appreciated thank you!
As a comment says: don't handle cond: turn it into if. for instance (this may not get all of the semantics of cond correct in Scheme and is casual about errors):
(define (rewrite-cond cond-expr)
(if (and (list? cond-expr)
(eqv? (first cond-expr) 'cond))
(rewrite-cond-clauses (rest cond-expr))
(error 'rewrite-cond "not a cond")))
(define (rewrite-cond-clauses clauses)
(if (null? clauses)
'#f
(let ((this (first clauses))
(more (rest clauses)))
(let ((test (first this))
(body (rest this)))
`(if ,(if (eqv? test 'else) '#t test)
(begin ,#body)
,(rewrite-cond-clauses more))))))
Now
> (rewrite-cond '(cond ((x) 1 3)
(y 2)
(else 3)))
(if (x) (begin 1 3) (if y (begin 2) (if #t (begin 3) #f)))

scheme - dynamic scope - why this is the return value?

why under dynamic scope this code will return error for "g not defined"?
when running ((ff) 5), at some point g will get a value (the f lambda) and will be inserted into the runtime stack.
(
let ((f (lambda (g)
(lambda (n)
(if (zero? n)
1
(* n ((g g) (- n 1))))))))
((f f) 5)
)
With dynamic scope you don't have closures. Eg.
(define val #f)
(define (get-val val)
(lambda ()
val))
(define getter (get-val 5))
(getter) ; => #f
With lexical scope val from get-val lives in the returned procedure as a free variable and would return 5, but in dynamic scope it stopped existing right ather the proceudre was returned. The val referred in the procedure is whatever bound val in the dynamic scope. Eg.
(let ((val 10))
(getter)) ; ==> 10
So val from the let became the closest binding with that name ad getter returned that.

CLOS: Format initialization argument list for make-instance

I've been scratching my head on this for a while now - maybe someone could shed some light on how to format an initialization argument list for 'make-instance' from a nested list containing (key value) sublists. Example:
(make-instance 'myclass :initarg1 1 :initarg2 2 :initarg3 '(a b))
If I have the keywords and values in a list like so:
'((initarg1 1) (initarg2 2) (initarg3 '(a b)))
Any help and pointers appreciated!
Thanks,
Marleynoe
(apply #'make-instance 'myclass
(loop for (parameter value) in '((initarg1 1) (initarg2 2) (initarg3 '(a b)))
collect (intern (symbol-name parameter) (find-package :keyword))
collect value))
(apply #'make-instance 'myclass
(mapcan #'(lambda (param)
(list (intern (symbol-name (car param)) (find-package :keyword))
(cadr param)))
'((initarg1 1) (initarg2 2) (initarg3 '(a b)))))
The idea is that each (initargk k) parameter pair is mapped to a fresh list (:initargk k) and then all of them are concatenated in order together. This is a typical pattern for the map function mapcan.

Common Lisp unbound variable / defmacro

I need to make the function defmacro for my meta-circular interpreter that can read this syntax:
pseudoscheme> (defmacro (minus x y) (list ‘- y x))
MINUS
pseudoscheme> (expand-macro '(minus 3 2))
(- 3 2)
When I use this:
(defmacro my-defmacro ((name &rest args) &body body)
(let ((form (gensym))(env (gensym)))
(progn
`(setf (macro-function ',name)
(lambda (,form ,env))
(destructuring-bind ,args (rest, form) ,#body))
name
)
)
)
and then:
(my-defmacro (min a b)(list '- a b))
I get this error:
Error: The variable MIN is unbound.
I can't understand why.
-----EDITED-----
If I use this:
(defmacro my-defmacro ((name &rest args) &body body)
(let ((form (gensym))(env (gensym)))
`(progn (setf (macro-function ',name)
(lambda (,form ,env))
(destructuring-bind ,args (rest, form) ,#body))
',name)
)
)
and then:
(my-defmacro (min a b)(list '- a b))
I get this error:
Error: Odd number of args to SETF: ((MACRO-FUNCTION (QUOTE PLUS)) (LAMBDA (#:G786 #:G787)) (DESTRUCTURING-BIND (A B) (REST #:G786) (LIST # A B)))
Your my-defmacro works for you host CL system, but I get the feeling you want macro capabilities in your interpreter and this won't do it. (except if ythe interpreter environment is the global host implementations environment, but that would make a lot of challenges)
I don't know how you do compound procedures in your evaluator but when my evaluator gets a (lambda (x) (+ x x)) it is turned into (compound-procedure <env> (x) (+ x x)). My macros turn into almost the same except the first element is compound-syntax.
Every evaluated operator has a tag which tells it what it is (one of primitive-syntax, primitive-procedure, compound-syntax, compound-procedure) and I only need a general way of dealing with those 4.
The real difference between a compound procedure and compound syntax is that the arguments gets evaluated for a procedure and in a compound syntax the result gets evaluated.
So. Have you implemented so that ((lambda (x) (+ x x)) 5) works? Well, then you'll almost implemented macros as well. This is of course not true for a compiler, since this approach would expand the code every time it's run instead of expanding once when the closure gets created. (Optimizations is no way to go on the first version anyway)
For your 'edited code' you have a misplaced paren:
(defmacro my-defmacro ((name &rest args) &body body)
(let ((form (gensym))(env (gensym)))
`(progn (setf (macro-function ',name)
(lambda (,form ,env)) ;; <== HERE
(destructuring-bind ,args (rest, form) ,#body))
',name)
)
)
which leads to setf having three subforms. Rewrite it like this (while using standard Lisp formatting):
(defmacro my-defmacro ((name &rest args) &body body)
(let ((form (gensym))
(env (gensym)))
`(progn (setf (macro-function ',name)
(lambda (,form ,env)
(destructuring-bind ,args (rest, form)
,#body)))
',name)))

Binding multiple definitions to one "variable" in scheme?

I think I read somewhere that you could bind multiple definitions to a single name in scheme. I know I might be using the terminology incorrectly. By this I mean it is possible to do the following (which would be really handy to defining an operator)?
I believe I read something like this (I know this is not real syntax)
(let ()
define operator "+"
define operator "-"
define operator "*"
define operator "/"))
I want to test another variable against every operator.
I'm not really sure what you're asking. Do you want a single procedure that can handle different types of arguments?
(define (super-add arg1 arg2)
(cond ((and (string? arg1) (string? arg2))
(string-append arg1 arg2))
((and (number? arg1) (number? arg2))
(+ arg1 arg2))
(else
(error "UNKNOWN TYPE -- SUPER-ADD"))))
(super-add "a" "b") => "ab"
(super-add 2 2) => 4
Are you interested in message passing?
(define (math-ops msg) ;<---- returns a procedure depending on the msg
(cond ((eq? msg 'add) +)
((eq? msg 'sub) -)
((eq? msg 'div) /)
((eq? msg 'multi) *)
(else
(error "UNKNOWN MSG -- math-ops"))))
((math-ops 'add) 2 2) => 4
((math-ops 'sub) 2 2) => 0
Also the proper syntax for a let binding:
(let (([symbol] [value])
([symbol] [value]))
([body]))
(let ((a 2)
(b (* 3 3)))
(+ a b))
=> 11
It will be very hard to help more than this without you clarifying what it is you are trying to do.
EDIT: After your comment, I have a little bit better of an idea for what you're looking for. There is not way to bind multiple values to the same name in the way that you mean. You are looking for a predicate that will tell you whether the thing you are looking at is one of your operators. From your comment it looked like you will be taking in a string, so that's what this is based on:
(define (operator? x)
(or (string=? "+" x) (string=? "-" x) (string=? "*" x) (string=? "/" x)))
If you are taking in a single string then you will need to split it into smaller parts. Racket has a built in procedure regexp-split that will do this for you.
(define str-lst (regexp-split #rx" +" [input str]))
You may be referring to the values construct, which "delivers arguments to a continuation". It can be used to return multiple values from a function. For example,
(define (addsub x y)
(values (+ x y) (- x y)))
(call-with-values
(lambda () (addsub 33 12))
(lambda (sum difference)
(display "33 + 12 = ") (display sum) (newline)
(display "33 - 12 = ") (display difference) (newline)))