Scheme sum-of-squares test - testing

I wrote a sum-of-squares function to test if a number n could be written as the sum of two squares. My code is as follows:
(define (square x) (* x x))
(define (sum-of-squares n)
(define (sum-of-squares-h k)
(cond ((= k n) #f)
((= n (+ (square(floor(sqrt k)))(square(floor(sqrt(- n k))))))#t)
(sum-of-squares-h (+ k 1))))
(sum-of-squares-h 1))
When I test things such as :
(sum-of-squares 1)
(sum-of-squares 2)
(sum-of-squares 4)
(sum-of-squares 8)
(sum-of-squares 10)
My output is:
#f
#t
2
2
#t
Where did I go wrong/ what can I do to fix this? I have seen other ways to go about doing this problem, but if someone could help me by using what I already have that would be great. I am not too familiar with the floor function so I may have used it incorrectly.
EDIT - code with a few tweaks
(define (square x) (* x x))
(define (sum-of-squares n)
(define (sum-of-squares-h k)
(cond ((= k n) #f)
((< n 4) #f)
((= n (+ (square(floor(sqrt k)))(square(floor(sqrt(- n k))))))#t)
(sum-of-squares-h (+ k 1))))
(sum-of-squares-h 1))

You forgot the else part in the last condition:
(define (sum-of-squares n)
(define (sum-of-squares-h k)
(cond ((= k n)
#f)
((= n (+ (square (floor (sqrt k)))
(square (floor (sqrt (- n k))))))
#t)
(else
(sum-of-squares-h (+ k 1)))))
(sum-of-squares-h 1))

Here is my function that finds all the ways that a number n can be written as the sum of squares:
(define (squares n)
(let loop ((x (isqrt n)) (y 0) (zs '()))
(cond ((< x y) zs)
((< (+ (* x x) (* y y)) n) (loop x (+ y 1) zs))
((< n (+ (* x x) (* y y))) (loop (- x 1) y zs))
(else (loop (- x 1) (+ y 1) (cons (list x y) zs))))))
The algorithm is from Dijkstra: x sweeps downward from the square root of n while y sweeps upward from zero; recursion stops when x and y cross. You can read more about it at my blog.

Related

Why can (and must) the variable x appear twice on the left side of the function definition? And what's the meaning?

I'm a green hand with Idris,and get confused with this definition, as I don't understand how it works.
The definitionare as follows.
sameS : (k : Nat)->(j : Nat)->(k = j)->((S k) = (S j))
sameS x x Refl=Refl
Let us start by breaking down the type signature:
sameS : (k : Nat) -> (j : Nat) -> (k = j) -> ((S k) = (S j))
sameS is a function.
sameS take the following arguments:
(k : Nat) a parameter k of type Nat
(j : Nat) a parameter j of type Nat
(k = j) A proof that k and j are equal
sameS returns:
((S k) = (S j)) proof that S k and S j are equal.
Now let us breakdown the definition:
sameS x x Refl = Refl
The type of Refl is a = a.
x is both the first and second argument because both are identical. We know this because the 3rd argument is Refl.
Refl is returned because S x = S x.

Scheme: Why am I getting this error: assertion-violation: argument of wrong type [car (car #{Unspecific})

I believe I have found it to be this function in my program but seems to fail before it even gets to the first line of find_best_candidates function:
(define (count-the-score candList voterList)
(display "Spot 3")
(cond
((null? voterList) 0)
(else
(cond
((or (= (car candList) 0) (= (car voterList) 0)) (+ 0 (count-the-score (cdr candList)(cdr voterList))))
((equal? (car candList) (car voterList)) (+ 1 (count-the-score (cdr candList)(cdr voterList))))
(else (- (count-the-score (cdr candList) (cdr voterList)) 1))
)
)
)
)
(define (find-max myList)
(define sortedList 0)
(display "Spot 4")
(cond
((null? myList) myList)
((null? (cdr myList)) myList)
(else
(set! sortedList (find-max (cdr myList)))
(cond
((null? sortedList) (cdr myList))
((null? (car sortedList)) (car myList))
((null? (car myList)) sortedList)
((= (car (cdr (car myList))) (car (cdr (car sortedList))))
(append sortedList (list (car myList)))
)
((> (car (cdr (car myList))) (car (cdr (car sortedList))))
(list (car myList))
)
(else
sortedList
)
)
(display "Spot 5")
)
)
)
(define (find_best_candidates Voter Candidates)
(display "Spot 2")
(define best 0)
(define score 0)
(define voterScore 0)
(define tempScore 0)
(define max_till 0)
(cond
((null? Candidates) '())
(else
(set! best (find_best_candidates Voter (cdr Candidates)))
(set! score (count-the-score Voter (cdr (car Candidates))))
(set! voterScore (list (car (car Candidates)) score))
(set! tempScore (append best (list voterScore)))
(set! max_till (find-max best))
)
)
(display "Spot 6")
)
(define (fetch-names myList)
(display "Spot 7")
(define prev_ans 0)
(define ll 0)
(cond
((null? (cdr myList)) (list(car (car myList))))
(else
(set! prev_ans (fetch-names (cdr) myList))
(set! ll (append (list (car (car myList))) prev_ans))
ll
)
)
(display "Spot 8")
)
;Main function;
(define (best_candidates Voter Candidates)
(display "Spot 1")
(fetch-names (find_best_candidates Voter Candidates))
(display "Spot END")
)
The data the is being imported is as follows:
(define (test1)
(best_candidates
'( 0 0 0 1 1 1 -1 -1 -1 1)
'((Adams 1 1 1 1 1 1 1 1 1 1)
(Grant -1 -1 -1 -1 -1 -1 -1 -1 -1 -1)
(Polk 1 -1 1 -1 1 -1 1 -1 1 -1)
(Jackson 1 0 1 0 1 0 1 0 1 0)
(Taft 0 -1 0 -1 0 -1 0 -1 0 -1)
(Ford 1 1 1 1 0 0 0 0 0 0)
(Madison 0 0 0 1 -1 0 0 -1 1 1)))
)
; should return (adams ford madison)
The error I end up receiving is:
assertion-violation: argument of wrong type [car]
(car #{Unspecific})
Found my issue. In fetch-names function, I had (set! prev_ans (fetch-names (cdr) myList)) which should have been written as (set! prev_ans (fetch-names (cdr myList))). I misplaced a parenthesis.
The result of the last expression in a function body is the result returned to the callee. Eg.
(define (best_candidates Voter Candidates)
(display "Spot 1")
(fetch-names (find_best_candidates Voter Candidates))
(display "Spot END"))
Will return the implementation defined "undefined value" as required by specification of display. In Racket it looks like #<void> and it is the same object from all of the procedures that are supposed to return an undefined value. Note that it is only undefined in the standard while in an implementation it is very defined so in Racket you can capture it in a variable. set! also returns an undefined value.
Some of your code expects a list, but gets #{Unspecific} which is probably your implementations version of the undefined value. Since it's not a pair car will signal an error.
If you payed for your Scheme course and learned to use display and set! your should ask for your money back. It's as if you already know a C language and try to assimilate Scheme. While you can learn Python that way since it is a C dialect, Scheme is not a C dialect so assimilation mostly works between lisp dialects and not across different language families.

find position of list using Lisp

Without using MEMBER, complete the following definition of a recursive function POS such
that if L is a list and E is an element of L then (POS E L) returns the position of the first
occurrence of E in L, but if L is a list and E is not an element of L then (POS E L) returns 0.
(DEFUN POS (E L)
(COND ((ENDP L) ... )
((EQUAL E (CAR L)) ... )
(T (LET ((X (POS E (CDR L))))
))))
that is my code
(defun pos (E L)
(cond ((endp L) 0)
((equal e (car L)) 1)
(T (let ((x (pos E (cdr L))))
(if (zerop x) x
(+ x 1)))))
im try to test the codition with
(POS '(A B) '((K) (3 R C) A (A B) (K L L) (A B))) => 4
but it give me the answer 4 and throw a error*** -
READ from # #>: an object cannot start with #\ )
I dont know what is #\
(defun pos (el l &optional (acc 1))
(cond ((null l) 0)
((equal el (car l)) acc)
(t (pos el (cdr l) (1+ acc)))))

An Idris proof about `mod`

I was trying to write a proof in Idris regarding the following subtraction-based mod operator:
mod : (x, y : Nat) -> Not (y = Z) -> Nat
mod x Z p = void (p Refl)
mod x (S k) _ = if lt x (S k) then x else helper x (minus x (S k)) (S k)
where total
helper : Nat -> Nat -> Nat -> Nat
helper Z x y = x
helper (S k) x y = if lt x y then x else helper k (minus x y) y
The theorem I wanted to prove is that the remainder as produced by "mod" above is always smaller than the divider. Namely,
mod_prop : (x, y : Nat) -> (p : Not (y=0))-> LT (mod x y p) y
I constructed a proof but was stuck by a final hole. My full code is pasted below
mod : (x, y : Nat) -> Not (y = Z) -> Nat
mod x Z p = void (p Refl)
mod x (S k) _ = if lt x (S k) then x else helper x (minus x (S k)) (S k)
where total
helper : Nat -> Nat -> Nat -> Nat
helper Z x y = x
helper (S k) x y = if lt x y then x else helper k (minus x y) y
lteZK : LTE Z k
lteZK {k = Z} = LTEZero
lteZK {k = (S k)} = let ih = lteZK {k=k} in
lteSuccRight {n=Z} {m=k} ih
lte2LTE_True : True = lte a b -> LTE a b
lte2LTE_True {a = Z} prf = lteZK
lte2LTE_True {a = (S _)} {b = Z} Refl impossible
lte2LTE_True {a = (S k)} {b = (S j)} prf =
let ih = lte2LTE_True {a=k} {b=j} prf in LTESucc ih
lte2LTE_False : False = lte a b -> GT a b
lte2LTE_False {a = Z} Refl impossible
lte2LTE_False {a = (S k)} {b = Z} prf = LTESucc lteZK
lte2LTE_False {a = (S k)} {b = (S j)} prf =
let ih = lte2LTE_False {a=k} {b=j} prf in (LTESucc ih)
total
mod_prop : (x, y : Nat) -> (p : Not (y=0))-> LT (mod x y p) y
mod_prop x Z p = void (p Refl)
mod_prop x (S k) p with (lte x k) proof lxk
mod_prop x (S k) p | True = LTESucc (lte2LTE_True lxk)
mod_prop Z (S k) p | False = LTESucc lteZK
mod_prop (S x) (S k) p | False with (lte (minus x k) k) proof lxk'
mod_prop (S x) (S k) p | False | True = LTESucc (lte2LTE_True lxk')
mod_prop (S x) (S Z) p | False | False = LTESucc ?hole
Once I run the type checker, the hole is described as follows:
- + Main.hole [P]
`-- x : Nat
p : (1 = 0) -> Void
lxk : False = lte (S x) 0
lxk' : False = lte (minus x 0) 0
--------------------------------------------------------------------------
Main.hole : LTE (Main.mod, helper (S x) 0 p x (minus (minus x 0) 1) 1) 0
I am not familiar with the syntax of Main.mod, helper (S x) 0 p x (minus (minus x 0) 1) 1 given in the idris-holes window. I guess (S x) 0 p are the three parameters of "mod" while (minus (minus x 0) 1) 1 are the three parameters of the local "helper" function of "mod"?
It seems that it's time to leverage an induction hypothesis. But how can I finish up the proof using induction?
(Main.mod, helper (S x) 0 p x (minus (minus x 0) 1) 1)
can be read as
Main.mod, helper - a qualified name for helper function, which is defined in the where clause of the mod function (Main is a module name);
Arguments of mod which are also passed to helper - (S x), 0 and p (see docs):
Any names which are visible in the outer scope are also visible in the
where clause (unless they have been redefined, such as xs here). A
name which appears only in the type will be in scope in the where
clause if it is a parameter to one of the types, i.e. it is fixed
across the entire structure.
Arguments of helper itself - x, (minus (minus x 0) 1) and 1.
Also below is another implementation of mod which uses Fin n type for the remainder in division by n. It turns out to be easier to reason about, since any value of Fin n is always less than n:
import Data.Fin
%default total
mod' : (x, y : Nat) -> {auto ok: GT y Z} -> Fin y
mod' Z (S _) = FZ
mod' (S x) (S y) with (strengthen $ mod' x (S y))
| Left _ = FZ
| Right rem = FS rem
mod : (x, y : Nat) -> {auto ok: GT y Z} -> Nat
mod x y = finToNat $ mod' x y
finLessThanBound : (f : Fin n) -> LT (finToNat f) n
finLessThanBound FZ = LTESucc LTEZero
finLessThanBound (FS f) = LTESucc (finLessThanBound f)
mod_prop : (x, y : Nat) -> {auto ok: GT y Z} -> LT (mod x y) y
mod_prop x y = finLessThanBound (mod' x y)
Here for convenience I used auto implicits for proofs that y > 0.

Why does this 'with' block spoil the totality of this function?

I'm trying to compute parity together with the floor of the half, over natural numbers:
data IsEven : Nat -> Nat -> Type where
Times2 : (n : Nat) -> IsEven (n + n) n
data IsOdd : Nat -> Nat -> Type where
Times2Plus1 : (n : Nat) -> IsOdd (S (n + n)) n
parity : (n : Nat) -> Either (Exists (IsEven n)) (Exists (IsOdd n))
I tried going with the obvious implementation of parity:
parity Z = Left $ Evidence _ $ Times2 0
parity (S Z) = Right $ Evidence _ $ Times2Plus1 0
parity (S (S n)) with (parity n)
parity (S (S (k + k))) | Left (Evidence _ (Times2 k)) =
Left $ rewrite plusSuccRightSucc k k in Evidence _ $ Times2 (S k)
parity (S (S (S ((k + k))))) | Right (Evidence _ (Times2Plus1 k)) =
Right $ rewrite plusSuccRightSucc k k in Evidence _ $ Times2Plus1 (S k)
This typechecks and works as expected. However, if I try to mark parity as total, Idris starts complaining:
parity is possibly not total due to: with block in parity
The only with block I see in parity is the one with the recursive call from parity (S (S n)) to parity n, but clearly that is well-founded, since n is structurally smaller than S (S n).
How do I convince Idris that parity is total?
It looks like a bug to me, because the following solution based on case passes the totality checker:
total
parity : (n : Nat) -> Either (Exists (IsEven n)) (Exists (IsOdd n))
parity Z = Left $ Evidence _ $ Times2 0
parity (S Z) = Right $ Evidence _ $ Times2Plus1 0
parity (S (S k)) =
case (parity k) of
Left (Evidence k (Times2 k)) =>
Left $ rewrite plusSuccRightSucc k k in Evidence _ $ Times2 (S k)
Right (Evidence k (Times2Plus1 k)) =>
Right $ rewrite plusSuccRightSucc k k in Evidence _ $ Times2Plus1 (S k)