I decided reading SICP a little, just to see what it is all about (I am not MIT student, actually already almost done with studying, this is no homework, but the content might be homework for someone.). Since I have installed sbcl, I have to change syntax a little, compared to the book. However, I don't understand why my solution to exercise 1.3 is not working:
(defun square (x) (* x x))
(defun sum-of-squares (x y)
(+ (square x) (square y)))
(defun sum-of-squares-two-max (x y z) (
(cond
((eq (min x y z) x) (sum-of-squares y z))
((eq (min x y z) y) (sum-of-squares x z))
(t (sum-of-squares x y))
)))
To load this I run sbcl --load exercise-1.3.lisp. When I load it, I get the error:
; file: /home/xiaolong/development/LISP/SICP/exercise-1.3.lisp
; in: DEFUN SUM-OF-SQUARES-TWO-MAX
; ((COND ((EQ (MIN X Y Z) X) (SUM-OF-SQUARES Y Z))
; ((EQ (MIN X Y Z) Y) (SUM-OF-SQUARES X Z)) (T (SUM-OF-SQUARES X Y))))
;
; caught ERROR:
; illegal function call
; (DEFUN SUM-OF-SQUARES-TWO-MAX (X Y Z)
; ((COND ((EQ # X) (SUM-OF-SQUARES Y Z)) ((EQ # Y) (SUM-OF-SQUARES X Z))
; (T (SUM-OF-SQUARES X Y)))))
;
; caught STYLE-WARNING:
; The variable X is defined but never used.
;
; caught STYLE-WARNING:
; The variable Y is defined but never used.
;
; caught STYLE-WARNING:
; The variable Z is defined but never used.
;
; compilation unit finished
; caught 1 ERROR condition
; caught 3 STYLE-WARNING conditions
Multiple things I don't understand:
Why are some variables not used? I use all of them in the conditional ...
Why is a function call illegal? How can I compose functions if I cannot call a function from inside a function? (I probably can, but I am doing it wrong?)
When I comment out the third function, it loads without errors.
I checked the syntax for the conditional multiple times already, cannot find the mistake.
How can I correct this code?
Get rid of the extra open paren.
(defun sum-of-squares-two-max (x y z)
(cond
((eq (min x y z) x) (sum-of-squares y z))
((eq (min x y z) y) (sum-of-squares x z))
(t (sum-of-squares x y))))
The issue is that, with the paren, the code will call whatever your cond will evaluate to (as with all first items within parens). Without the paren, it knows that the result of the function is whatever the cond evaluates to.
Also, a general warning: SICP uses scheme, so you'll see some small differences between the book and what common lisp macros force you into.
Related
I'm trying to create a function that gets the sum of the square of the larger 2 of 3 numbers passed in. (Its exercise 1.3 in SICP)
When I run the following code I get the error ";The object #f is not applicable." If I switch the 3 and the 1 in my function call the error message will say #t instead of #f.
(define (sumOfSquareOfLargerTwoNumbers a b c) (
cond (
( (and (> (+ a b) (+ a c) ) (> (+ a b) (+ b c) ) ) (+ (square a) (square b) ) )
( (and (> (+ a c) (+ a b) ) (> (+ a c) (+ b c) ) ) (+ (square a) (square c) ) )
( (and (> (+ b c) (+ a b) ) (> (+ b c) (+ a c) ) ) (+ (square b) (square c) ) )
)
))
(sumOfSquareOfLargerTwoNumbers 1 2 3)
I was assuming the appropriate condition would return true and I'd get the square of the larger two numbers. Could someone please explain why I'm getting this error instead?
There are too many brackets in front of cond and that's causing the problem:
(cond (((and
The proper syntax for your solution should be:
(define (sumOfSquareOfLargerTwoNumbers a b c)
(cond ((and (> (+ a b) (+ a c)) (> (+ a b) (+ b c)))
(+ (square a) (square b)))
((and (> (+ a c) (+ a b)) (> (+ a c) (+ b c)))
(+ (square a) (square c)))
((and (> (+ b c) (+ a b)) (> (+ b c) (+ a c)))
(+ (square b) (square c)))))
What was happening is that the condition evaluated to a boolean, and the unexpected surrounding brackets made it look like a procedure application, so you ended up with something like this:
(#t 'something)
Which of course fails, because #t or #f are not procedures and cannot be applied. Just be careful with the brackets and use a good IDE with syntax coloring and code formatting, and you won't have this problem again.
When using mixed assert and assert-soft in optimization tasks, e.g. maximize, the soft assertions are disregarded, if they would lead to a non-optimal result.
Is it possible to restrict the "softness" to the satisfiability search only? I.e.: If the soft assertion is satisfiable at all, it is kept and then treated as "hard" assertion in the optimization?
Example exhibiting the aforementioned:
(declare-fun x () Int)
(declare-fun y () Int)
(assert (< (+ x y) (* x y)))
(assert (>= x 0))
(assert (>= y x))
;(assert-soft (>= (* 4 x) y)); x->2, y->500
(assert (>= (* 4 x) y)); x->16, y->62
(assert (<= (* x y) 1000))
(maximize (+ x y))
(set-option :opt.priority pareto)
(check-sat)
(get-value (x y (+ x y) (* x y)))
(check-sat)
(get-value (x y (+ x y) (* x y)))
;...
This would be required to fulfill the following use case:
Given a complex fixed ruleset on a large (>1000) number of variables (mostly having a finite domain), a user can choose the desired values for any of those, which may lead to conflicts with the ruleset.
The individual values for a variable have ratings/weights.
So, given a set of user-selected (possibly conflicting) selections, the ruleset itself and finally the ratings of the set of all possible selections, one solution for all variables is to be found, which, while respecting all non-conflicting selections by the user, maximizes the total rating score.
I had the idea of using assert-soft for user selections to cancel out conflicting ones, while combining it with the optimization of z3 to get the "best" solution. However, this failed, which is the reason for this question.
My answer is yes, if you do it incrementally.
Assume that the set of soft-clauses has only a unique Boolean assignment which makes its associated MaxSMT problem optimal.
Then, it is easy to make satisfiable soft-clauses hard by fixing the value of the associated objective function. Although z3 does not allow to put explicit constraints on the name of a soft clause group (AFAIK), one can do it implicitly by using a lexicographic multi-objective combination rather than a pareto one.
Now, in your example we can safely switch from pareto to lexicographic search because there is only one extra objective function in addition to the one implicitly defined by assert-soft. Assuming the value of the assert-soft group being fixed, the whole problem degenerates to a single-objective formula which in turn has always at-most-one Pareto-optimal solution.
Of course, this is not possible if one plans to add more objectives to the formula. In this case, the only option is to solve the formula incrementally, as follows:
(set-option:produce-models true)
(declare-fun x () Int)
(declare-fun y () Int)
(declare-fun LABEL () Bool)
(assert (and
(or (not LABEL) (>= (* 4 x) y))
(or LABEL (not (>= (* 4 x) y)))
)) ; ~= LABEL <-> (>= (* 4 x) y)
(assert-soft LABEL)
(assert (< (+ x y) (* x y)))
(assert (>= x 0))
(assert (>= y x))
(assert (>= (* 4 x) y))
(assert (<= (* x y) 1000))
(check-sat)
(get-model)
(push 1)
; assert LABEL or !LABEL depending on its value in the model
(maximize (+ x y))
; ... add other objective functions ...
(set-option :opt.priority pareto)
(check-sat)
(get-value (x y (+ x y) (* x y)))
(check-sat)
(get-value (x y (+ x y) (* x y)))
...
(pop 1)
This solves the MaxSMT problem first, fixes the Boolean assignment of the soft-clauses in a way that makes them hard, and then proceeds with optimizing multiple objectives with the pareto combination.
Note that, if the MaxSMT problem admits multiple same-weight solutions for the same optimal value, then the previous approach would discard them and focus on only one assignment. To circumvent this, the ideal solution would be to fix the value of the MaxSMT objective rather than fixing its associated Boolean assignment, e.g. as follows:
(set-option:produce-models true)
(declare-fun x () Int)
(declare-fun y () Int)
(declare-fun LABEL () Bool)
(assert-soft (>= (* 4 x) y) :id soft)
(assert (< (+ x y) (* x y)))
(assert (>= x 0))
(assert (>= y x))
(assert (>= (* 4 x) y))
(assert (<= (* x y) 1000))
(minimize soft)
(check-sat)
(get-model)
(push 1)
; assert `soft` equal to its value in model, e.g.:
; (assert (= soft XXX )))
(maximize (+ x y))
; ... add other objective functions ...
(set-option :opt.priority pareto)
(check-sat)
(get-value (x y (+ x y) (* x y)))
(check-sat)
(get-value (x y (+ x y) (* x y)))
...
(pop 1)
At the time being, this kind of syntax for objective combination is supported by OptiMathSAT only. Unfortunately, OptiMathSAT does not yet support non-linear arithmetic in conjunction with optimization, so it can't be reliably used on your example.
Luckily, one can still use this approach with z3!
If there is only one extra objective function in addition to the group of soft-clauses, one can still use the lexicographic combination rather than pareto one and get the same result.
Otherwise, if there are multiple objectives in addition to the group of soft-clauses, it suffices to explicitly encode the MaxSMT problem with a Pseudo-Boolean objective as opposed to using the assert-soft command. In this way, one retains full control of the associated objective function and can easily fix its value to any number. Note, however, that this might decrease the performance of the solver in dealing with the formula depending on the quality of the MaxSMT encoding.
I apologize in advance for this likely silly question :)
Suppose, I have a list of strings like
(define func-names '("add" "sub" "mul"))
And there are also functions defined like so
(define (add x y)
(+ x y))
(define (sub x y)
(- x y))
(define (mul x y)
(* x y))
As you can see, values of the strings in the list correspond to the names of the functions.
I need a way to iterate through the list and call the function that corresponds to a string value. Something like
(define (all-ops x y)
(map (lambda (name) (string->proc name x y)) func-names))
where string->proc is what I'm looking for. Something like Ruby's send/public_send method, if you're familiar with Ruby.
I'm mostly interested in answers applicable to Racket.
Thank you.
EDIT;
And I've forgotten to mention that there may be a million of function names, so cond, match would be tedious to use here.
Consider making a hash table that maps strings to function values.
That said, you can do as follows:
#lang racket
(define (add x y)
(+ x y))
(define ns (variable-reference->namespace (#%variable-reference)))
(define (string->procedure s)
(define sym (string->symbol s))
(eval sym ns))
(string->procedure "add")
((string->procedure "add") 1 2)
See also http://blog.racket-lang.org/2011/10/on-eval-in-dynamic-languages-generally.html
Define a function sum, which takes two numbers, or two real functions, and returns their sum. E.g.
(sum 1 2) => 3
((sum cos exp) 0) => 2
I get that for the sum of two numbers the code would be the following:
(define sum (lambda (x y)
(+ x y)))
But what would be the code for the two real functions...? How would I do this? can anyone please help?
Also how would I do this:
Define a function sum-all which works like sum, but works on a list of numbers or a list of functions. Assume the list contains at least one element.
E.g.
(sum-all (list 1 2 3)) => 6
((sum-all (list cos sin exp)) 0) => 2
Note: this is not homework... I was going through a past midterm.
For the first part of your question, I'll have to agree with PJ.Hades that this is the simplest solution:
(define (sum x y)
(if (and (number? x) (number? y))
(+ x y)
(lambda (n)
(+ (x n) (y n)))))
For the second part, we can make good use of higher-order procedures for writing a simple solution that is a generalization of the previous one:
(define (sum-all lst)
(if (andmap number? lst)
(apply + lst)
(lambda (n)
(apply + (map (lambda (f) (f n)) lst)))))
In both procedures, I'm assuming that all the operands are of the same kind: they're either all-numbers or all-functions, as inferred from the sample code provided in the question.
Do you mean this?
(define (sum a b)
(if (and (number? a) (number? b))
(+ a b)
(lambda (x)
(+ (a x) (b x)))))
(define (sum lst)
(cond
[(empty? lst) 0]
[else (foldr + 0 lst)]))
((lambda (a b) (+ a b)) 4 5)
this how it is done using lambda.
using define we can write as follows
(define (sum a b) (+ a b))
I'm a little rusty with my Scheme, so perhaps there's a better way to do this, but you could do:
(define (sum-all lst)
(define (sum-funcs-helper funcs x)
(if (empty? funcs)
0
(+ ((car funcs) x)
(sum-funcs-helper (cdr funcs) x))))
(if (empty? lst)
0 ;; Beats me what this is supposed to return.
(if (number? (car lst))
(apply + lst)
(lambda (x) (sum-funcs-helper lst x)))))
I'm trying to proof the following with Z3 SMT Solver: ((x*x) + x) = ((~x * ~x) + ~x).
This is correct, because of overflow semantic in the c programming language.
Now I have written the following smt-lib code:
(declare-fun a () Int)
(define-fun myadd ((x Int) (y Int)) Int (mod (+ x y) 4294967296) )
(define-fun mynot ((x Int)) Int (- 4294967295 (mod x 4294967296)) )
(define-fun mymul ((x Int) (y Int)) Int (mod (* x y) 4294967296) )
(define-fun myfun1 ((x Int)) Int (myadd (mynot x) (mymul (mynot x) (mynot x))) )
(define-fun myfun2 ((x Int)) Int (myadd x (mymul x x)) )
(simplify (myfun1 0))
(simplify (myfun2 0))
(assert (= (myfun1 a) (myfun2 a)))
(check-sat)
(exit)
The output from z3 is:
0
0
unsat
Now my question: Why is the result "unsat"? The simplify command in my code shows that it is possible to get a valid allocation so that myfun1 and myfun2 have the same result.
Is something wrong with my code or is this a bug in z3?
Please can anybody help me. Thx
The incorrect result was due to a bug in the Z3 formula/expression preprocessor. The bug has been fixed, and is already part of the current release (v4.3.1). The bug affected benchmarks that use formulas of the form: (mod (+ a b)) or (mod (* a b)).
We can retry the example online here, and get the expected result.