Scheme R5RS contract violation - scheme

The code below is the answer given by the professor for a question in my intro to scheme course but it comes out with an error. Cannot see why.
#!r5rs
(define (make-complex a b) (cons a b))
(define (real x) (car x))
(define (imag x) (cdr x))
(define (complex-sqrt x)
(define (sgn v)
(cond ((< v 0) -1)
((= v 0) 0)
(else 1)))
(let ((root (sqrt (+ (* (real x) (real x))
(* (imag x) (imag x))))))
(make-complex (sqrt (/ (+ (real x) root) 2))
(* (sgn (imag x))
(sqrt (/ (- root (real x)) 2))))))
(complex-sqrt 7)
;; ERROR mcar: contract violation
;; expected: mpair?
;; given: 7
I took a screenshot of the error with trace illustartion while running it in DrRacket.

Here's your code transcribed. Please consider posting the actual code rather than a screenshot in future.
(define (make-complex a b) (cons a b))
(define (real x) (car x))
(define (imag x) (cdr x))
(define (complex-sqrt x)
(define (sgn v)
(cond ((< v 0) -1)
((= v 0) 0)
(else 1)))
(let ((root (sqrt (+ (* (real x) (real x))
(* (imag x) (imag x))))))
(make-complex (sqrt (/ (+ (real x) root) 2))
(* (sgn (imag x))
(sqrt (/ (- root (real x)) 2))))))
Was the (complex-sqrt 7) part provided by your professor too? We're trying to get the square root of a complex number, so we should pass in a complex number:
(complex-sqrt (make-complex 5 2))
'(2.27872385417085 . 0.43884211690225433)
Which according to https://www.wolframalpha.com/input/?i=sqrt(2i%2B5) is correct!

The implementation of complex-sqrt is an unsafe one. What that means is that it assumes you pass it a complex number, in this case something created with make-complex.
To fix this you need to check if the argument is complex:
;; Not 100%. Should use `struct` to not
;; mix with random pairs that happens to have numeric parts
(define (complex? x)
(and (pair? x)
(number? (car x))
(number? (cdr x))))
;; The original code is renamed to unsafe-complex-sqrt
(define (complex-sqrt x)
(if (complex? x)
(unsafe-complex-sqrt x)
(raise-argument-error 'complex-sqrt "complex?" x)))
Now you can test it:
(complex-sqrt (make-complex 7 0))
; ==> (2.6457513110645907 . 0)
(complex-sqrt 7)
; ERROR complex-sqrt: contract violation
; expected: complex?
; given: 7
Perfect. Now it says you have mot passed the required complex number to a function that requires a complex number to work.
So what happend in the original code?
In unsafe-complex-sqrt it uses car and cdr which are safe operations that signal contract violation if the argument x supplied isn't #t for (pair? x).
Racket uses mcons in its #!r5rs implementation and thus the errors refer to every pair/list function in R5RS prefixed with an m since the error doesn't pay attention to renaming.

Related

How to make this function elegant

In response to the following exercise from the SICP,
Exercise 1.3. Define a procedure that takes three numbers as arguments
and returns the sum of the squares of the two larger numbers.
I wrote the following (correct) function:
(define (square-sum-larger a b c)
(cond ((or (and (> a b) (> b c)) (and (> b a) (> a c))) (+ (* a a) (* b b)))
((or (and (> a c) (> c b)) (and (> c a) (> a b))) (+ (* a a) (* c c)))
((or (and (> b c) (> c a)) (and (> c b) (> b a))) (+ (* b b) (* c c)))))
Unfortunately, that is one of the ugliest functions I've written in my life. How do I
(a) Make it elegant, and
(b) Make it work for an arbitrary number of inputs?
I found an elegant solution (though it only works for 3 inputs):
(define (square-sum-larger a b c)
(+
(square (max a b))
(square (max (min a b) c))))
If you're willing to use your library's sort function, this becomes easy and elegant.
(define (square-sum-larger . nums)
(define sorted (sort nums >))
(let ((a (car sorted))
(b (cadr sorted)))
(+ (* a a) (* b b))))
In the above function, nums is a "rest" argument, containing a list of all arguments passed to the function. We just sort that list in descending order using >, then square the first two elements of the result.
I don't know if it's elegant enough but for a 3 argument version you can use procedure abstraction to reduce repetition:
(define (square-sum-larger a b c)
(define (square x)
(* x x))
(define (max x y)
(if (< x y) y x))
(if (< a b)
(+ (square b) (square (max a c)))
(+ (square a) (square (max b c)))))
Make it work for an arbitrary number of inputs.
(define (square-sum-larger a b . rest)
(let loop ((a (if (> a b) a b)) ;; a becomes largest of a and b
(b (if (> a b) b a)) ;; b becomes smallest of a and b
(rest rest))
(cond ((null? rest) (+ (* a a) (* b b)))
((> (car rest) a) (loop (car rest) a (cdr rest)))
((> (car rest) b) (loop a (car rest) (cdr rest)))
(else (loop a b (cdr rest))))))
A R6RS-version using sort and take:
#!r6rs
(import (rnrs)
(only (srfi :1) take))
(define (square-sum-larger . rest)
(apply +
(map (lambda (x) (* x x))
(take (list-sort > rest) 2))))
You don't need to bother sorting you just need the find the greatest two.
(define (max-fold L)
(if (null? L)
#f
(reduce (lambda (x y)
(if (> x y) x y))
(car L)
L)))
(define (remove-num-once x L)
(cond ((null? L) #f)
((= x (car L)) (cdr L))
(else (cons (car L) (remove-once x (cdr L))))))
(define (square-sum-larger . nums)
(let ((max (max-fold nums)))
(+ (square max)
(square (max-fold (remove-num-once max nums))))))
(square-sum-larger 1 8 7 4 5 6 9 2)
;Value: 145

How to do square in RACKET

Here is my code:
(define (squares 1st)
(let loop([1st 1st] [acc 0])
(if (null? 1st)
acc
(loop (rest 1st) (* (first 1st) (first 1st) acc)))))
My test is:
(test (sum-squares '(1 2 3)) => 14 )
and it's failed.
The function input is a list of number [1 2 3] for example, and I need to square each number and sum them all together, output - number.
The test will return #t, if the correct answer was typed in.
This is rather similar to your previous question, but with a twist: here we add, instead of multiplying. And each element gets squared before adding it:
(define (sum-squares lst)
(if (empty? lst)
0
(+ (* (first lst) (first lst))
(sum-squares (rest lst)))))
As before, the procedure can also be written using tail recursion:
(define (sum-squares lst)
(let loop ([lst lst] [acc 0])
(if (empty? lst)
acc
(loop (rest lst) (+ (* (first lst) (first lst)) acc)))))
You must realize that both solutions share the same structure, what changes is:
We use + to combine the answers, instead of *
We square the current element (first lst) before adding it
The base case for adding a list is 0 (it was 1 for multiplication)
As a final comment, in a real application you shouldn't use explicit recursion, instead we would use higher-order procedures for composing our solution:
(define (square x)
(* x x))
(define (sum-squares lst)
(apply + (map square lst)))
Or even shorter, as a one-liner (but it's useful to have a square procedure around, so I prefer the previous solution):
(define (sum-squares lst)
(apply + (map (lambda (x) (* x x)) lst)))
Of course, any of the above solutions works as expected:
(sum-squares '())
=> 0
(sum-squares '(1 2 3))
=> 14
A more functional way would be to combine simple functions (sum and square) with high-order functions (map):
(define (square x) (* x x))
(define (sum lst) (foldl + 0 lst))
(define (sum-squares lst)
(sum (map square lst)))
I like Benesh's answer, just modifying it slightly so you don't have to traverse the list twice. (One fold vs a map and fold)
(define (square x) (* x x))
(define (square-y-and-addto-x x y) (+ x (square y)))
(define (sum-squares lst) (foldl square-y-and-addto-x 0 lst))
Or you can just define map-reduce
(define (map-reduce map-f reduce-f nil-value lst)
(if (null? lst)
nil-value
(map-reduce map-f reduce-f (reduce-f nil-value (map-f (car lst))))))
(define (sum-squares lst) (map-reduce square + 0 lst))
racket#> (define (f xs) (foldl (lambda (x b) (+ (* x x) b)) 0 xs))
racket#> (f '(1 2 3))
14
Without the use of loops or lamdas, cond can be used to solve this problem as follows ( printf is added just to make my exercises distinct. This is an exercise from SICP : exercise 1.3):
;; Takes three numbers and returns the sum of squares of two larger number
;; a,b,c -> int
;; returns -> int
(define (sum_sqr_two_large a b c)
(cond
((and (< a b) (< a c)) (sum-of-squares b c))
((and (< b c) (< b a)) (sum-of-squares a c))
((and (< c a) (< c b)) (sum-of-squares a b))
)
)
;; Sum of squares of numbers given
;; a,b -> int
;; returns -> int
(define (sum-of-squares a b)
(printf "ex. 1.3: ~a \n" (+ (square a)(square b)))
)
;; square of any integer
;; a -> int
;; returns -> int
(define (square a)
(* a a)
)
;; Sample invocation
(sum_sqr_two_large 1 2 6)

Issues with conditionals in Scheme

I'm using Scheme with the full Swindle package, and I'm trying to use conditionals to recursively determine evenness/oddity of integers. My code is as follows:
(define (odd? x)(
(cond
((= x 0) '#f)
((= x 1) '#t)
((= (even? (- x 1)) #t) '#f)
(else '#t))))
(define (even? x)(
(cond
((= x 0) '#f)
((= x 2) '#t)
((= (odd? (- x 1)) #t) '#f)
(else '#t))))
However, when I run (even? x) or (odd? x) [x is some number, doesn't matter what, as I get the same error] I get: application: not a procedure;
expected a procedure that can be applied to arguments
given: #t
arguments...: [none]
Can anyone help? Thanks. I'm not 100% familiar with ideal Scheme syntax, so it might be that.
You have an erroneous pair of parentheses surrounding the cond expression (that's causing the error reported). But also, there are way too many conditions in each procedure, and because you're using = to compare numbers with boolean values, there will be a point where a contract violation will occur. For fixing that you can replace = with equal? in here:
((equal? (even? (- x 1)) #t) '#f)
And in here:
((equal? (odd? (- x 1)) #t) '#f)
But then, the procedures will still give an incorrect result:
(even? 5)
=> #t
(odd? 7)
=> #f
Honestly, I think it'd better to simplify the implementation, that will solve all the problems. Try this instead:
(define (odd? x)
(cond ((= x 0) #f)
(else (even? (- x 1)))))
(define (even? x)
(cond ((= x 0) #t)
(else (odd? (- x 1)))))
Now we'll get correct answers:
(even? 4)
=> #t
(even? 5)
=> #f
(odd? 6)
=> #f
(odd? 7)
=> #t
Any Scheme form in parentheses is an application, like (sin 42) or (42 sin). The first calls sin as a function with argument 42 and produces a value; the second tries to call 42 with an argument sin, but 42 is no procedure, so this causes an error. Similarly (42) is an application with no arguments; still it must have a procedure to be applied as its first part, to be called with no arguments, right? In Scheme, parentheses matter, they are not just for grouping stuff (as they may be in some other languages). So the extra parentheses cause an extra attempt to evaluate the result, which is a Boolean, i.e. not a procedure, so this is an error.
Then, '#f is just #f; similarly for #t (they both evaluate to themselves); and a condition (= test #t)1 (equal? test #t) is the same as just test (produces the same set of Boolean results) ((1 we can't use = to compare Booleans, it is supposed to be used with numbers only)):
(define (odd? x)
(cond
((= x 0) #f)
((= x 1) #t)
((even? (- x 1)) #f)
(else #t)))
Also, (if test #f else...) is the same as (if (not test) else... #f):
(define (odd? x)
(cond
((= x 0) #f)
((= x 1) #t)
((not (even? (- x 1))) #t)
(else #f))) ; (else ...) is like (#t ...)
using logical connectives, the clauses with the same outcome can be merged, and mutually exclusive clauses can be rearranged (mutual exclusivity can be achieved with explicit guards):
(define (odd? x)
(cond
((and (/= x 0) ; a guard
(or (= x 1)
(not (even? (- x 1))))) #t)
((or (= x 0) #t) #f)))
but (cond (test #t) (else #f) is (if test #t #f) which is just test:
(define (odd? x) (and (> x 0) ; `>` is better
(or (= x 1)
(not (even? (- x 1))))))
The guard (> x 0) prevents the fall-through for negative xes.
But then, this is completely wrong. For n to be odd, n-1 must be even, not the opposite!
(define (odd? x) (and (> x 0) ; work only for positive integers
(or (= x 1)
(even? (- x 1)))))
We could write (not (odd? (- x 1))), but then it wouldn't be tail recursive. It would be tail recursive modulo cons (not serving as a "constructor"), but for some historic fluke of a reason2, TRMC optimization isn't required of a Scheme implementation. The last expression in and and or forms is, in fact, in tail position. But not in not. ((2 despite being described as early as 1974.))
Repeat the same for your definition of even?.

How do I use a pair to find which of two functions will evaluate the largest value? Scheme

Basically there is a pair made up of two functions and the code has to take the pair input x to find the highest evaluation for x and print that evaluation.
I receive the error:
car: contract violation expected: pair? given: 4
define (max x)
(lambda (x) ;I wanted lambda to be the highest suitable function
(if (> (car x) (cdr x))
(car x)
(cdr x))))
(define one-function (lambda (x) (+ x 1)))
(define second-function (lambda (x) (+ (* 2 x) 1))) ;my two functions
((max (cons one-function second-function)) 4)
And where are the functions being called? And you have two parameters called x, they must have different names. Try this:
(define (max f) ; you must use a different parameter name
(lambda (x)
(if (> ((car f) x) ((cdr f) x)) ; actually call the functions
((car f) x)
((cdr f) x))))
Now it'll work as expected:
((max (cons one-function second-function)) 4)
=> 9

Translation of Scheme code for Sierpinski carpet

I found code for generating Sierpinski carpet at http://rosettacode.org/wiki/Sierpinski_carpet#Scheme - but it won't run in the DrRacket environment or WeScheme. Could someone provide solutions for either environments?
It looks like this code runs fine in DrRacket after prepending a
#lang racket
line indicating that the code is written in Racket. I can provide more detail if this is not sufficient.
I've translated the program to run under WeScheme. I've made a few changes: rather than use (display) and (newline), I use the image primitives that WeScheme provides to make a slightly nicer picture. You can view the running program and its source code. For convenience, I also include the source here:
;; Sierpenski carpet.
;; http://rosettacode.org/wiki/Sierpinski_carpet#Scheme
(define SQUARE (square 10 "solid" "red"))
(define SPACE (square 10 "solid" "white"))
(define (carpet n)
(local [(define (in-carpet? x y)
(cond ((or (zero? x) (zero? y))
#t)
((and (= 1 (remainder x 3)) (= 1 (remainder y 3)))
#f)
(else
(in-carpet? (quotient x 3) (quotient y 3)))))]
(letrec ([outer (lambda (i)
(cond
[(< i (expt 3 n))
(local ([define a-row
(letrec ([inner
(lambda (j)
(cond [(< j (expt 3 n))
(cons (if (in-carpet? i j)
SQUARE
SPACE)
(inner (add1 j)))]
[else
empty]))])
(inner 0))])
(cons (apply beside a-row)
(outer (add1 i))))]
[else
empty]))])
(apply above (outer 0)))))
(carpet 3)
Here is the modified code for WeScheme. WeScheme don't support do-loop syntax, so I use unfold from srfi-1 instead
(define (unfold p f g seed)
(if (p seed) '()
(cons (f seed)
(unfold p f g (g seed)))))
(define (1- n) (- n 1))
(define (carpet n)
(letrec ((in-carpet?
(lambda (x y)
(cond ((or (zero? x) (zero? y))
#t)
((and (= 1 (remainder x 3)) (= 1 (remainder y 3)))
#f)
(else
(in-carpet? (quotient x 3) (quotient y 3)))))))
(let ((result
(unfold negative?
(lambda (i)
(unfold negative?
(lambda (j) (in-carpet? i j))
1-
(1- (expt 3 n))))
1-
(1- (expt 3 n)))))
(for-each (lambda (line)
(begin
(for-each (lambda (char) (display (if char #\# #\space))) line)
(newline)))
result))))

Resources