Racket Contract Failing Where It Shouldn't - lisp

I have a struct that represents a move
(struct move (tile x y rotations) #:prefab)
Pass is also allowed, so I have a bool that test for an action:
(define (action? v)
(if (or (pass? v)
(move? v))
#t
;; else
#f
)
)
I can declare a move like
(define test (move (tile 'blue (list (posn 0 0 ) (posn 1 0) (posn 2 0) (posn 3 0) (posn 3 1))) 2 4 0))
And when I test for action? it passes:
(action? test)
#t
However, when I use this file on a different module, the move structure is not accepted as a valid move:
state-transition: contract violation
expected: (and/c action? ???)
given: '#s(move #s(tile blue (#s(posn 0 0) #s(posn 1 0) #s(posn 2 0) #s(posn 3 0) #s(posn 3 1))) 2 4 0)
which isn't: ???
Here is the state-transition contract provided by the teacher:
[state-transition (->i ([s state?]
[a (s) (and/c action?
(cut state-action-legal? <> s))])
[result state?])]
So I have basically the same object in two places. In one of them it passes the test, and in the other one it fails and a contract is broken. Why is this happening?
Edit
Here is the definition of state-action-legal?
(define (state-action-legal? state action)
(not (state-action-violation state action))
)
And state-action-violation returns string indicating the reason the action is not legal or #F if the action is legal. I know they are both working properly because we tested them manually and the teacher provided unit tests to ensure proper implementation and these functions pass all of them.
End edit
Thank you for your help.

Related

How to filter random number generator and not include 0

How do I fix the random: expects (or/c (integer-in 1 4294967087) pseudo-random-generator?) or a pseudo-random-generator, given 0 error?
(require 2htdp/universe)
(require 2htdp/image)
(define-struct sample(x))
(define BACKGROUND (empty-scene 100 100))
(define CIRCLE (ellipse 10 10 "solid" "red"))
(define (rand d)
(random d))
(define (randoll d)
(cond [(even? (rand d))(rand d)]
[(< (rand d) 6)7]
[(= (rand d) 0)7]
[else 7]))
(define (main ws)
(big-bang ws
(on-tick randoll)
(to-draw render)))
(define (render d)
(place-image CIRCLE (randoll d) 6 BACKGROUND))
(main 100)
random: expects (or/c (integer-in 1 4294967087) pseudo-random-generator?) or a pseudo-random-generator, given 0
Was expecting for it to continuously changing places at even numbers but this happened
How about adding 1 to the parameter passed to random? as long as the input is >= 0 it'll work fine - the error you're receiving is simply stating that you can't pass 0 as parameter to random:
(define (rand d)
(random (+ d 1)))
By the way, randoll doesn't look right. Why do you test if the random value is even, just to return another random value, which we don't know if it's going to be even? And it appears that if the random value is zero or in all the other cases you just want to return 7. Better try this, if it fits what you intended:
(define (randoll d)
(let ([r (rand d)]) ; call `rand` exactly once
(cond [(zero? r) 7] ; 0 is even, so check this first
[(even? r) r] ; return `r` only if it's even
[else 7]))) ; default case
I'm not sure what's the expected range of values for randoll, but it looks to me that most of the time it'll just return 7. Is this what you want?

why is racket code returning void : Sudoku

(define (solver row col board boolboard) ;solve the game
(if (equal? row 9)
board
(if (equal? (get-value boolboard row col) #t)
(begin
(for ([ite '(1 2 3 4 5 6 7 8 9)]) ;true
(when (equal? (check-available row col ite board) #t) ;should be careful here
(begin
(let ([new-board (set-value board row col ite)])
(if (equal? col 8)
(solver (+ 1 row) 0 new-board boolboard)
(solver row (+ 1 col) new-board boolboard)))
)
)
))
(if (and (equal? col 8) (equal? row 8)) ;false
board
(if (equal? col 8)
(solver (+ 1 row) 0 board boolboard)
(solver row (+ 1 col) board boolboard)
)))
)
)
This is the soduku solver. I've checked that the solver finally reached (if (equal? row 9) so it gets the board. But the function still returns #. I dont know why it is not returning the board.
Anyone could help me with that?
A general rule for fixing these types of bugs:
If it's returning something you don't expect (here, #<void>), then look for the cases in your function that could return that. You determined that the base case returns what you expect, but you have to check the other cases too.
The next case has a begin with a for inside of it. The for form always returns #<void> no matter what the body expression returned on any iteration.
So there's your case where it's returning #<void>. The for form evaluates the body of the loop on each iteration, but ignores the return values.
Because of this, for is pretty much never what you want. Normally forms like for/list, for/or, and for/fold are much more useful. In this case, for/first looks like it could be what you meant.
If you translate it blindly,
(for/first ([ite '(1 2 3 4 5 6 7 8 9)])
(when (equal? (check-available row col ite board) #t)
(let ([new-board (set-value board row col ite)])
(if (equal? col 8)
(solver (+ 1 row) 0 new-board boolboard)
(solver row (+ 1 col) new-board boolboard)))))
Then this still doesn't work because it still returns #<void> a lot of the time, since the when form returns #<void> when the condition is false. The for/first form isn't magic. It doesn't see that the when form fails or use that information to go to the next clause. To make for/first check the condition and go on to the next clause if it's false, use a #:when clause after the [ite ...].
(for/first ([ite '(1 2 3 4 5 6 7 8 9)]
#:when (equal? (check-available row col ite board) #t))
(let ([new-board (set-value board row col ite)])
(if (equal? col 8)
(solver (+ 1 row) 0 new-board boolboard)
(solver row (+ 1 col) new-board boolboard))))
The for/first form will evaluate the body for the first iteration where the #:when condition is true, and return that.
However, if the #:when condition is never true for any iteration, the for/first form will return false, so that will cause your solver function to return false.
But that means that the recursive calls within the for/first form could return false. If that happens, what should it do? You probably want to go to the next iteration of the loop. For that, you can use for/or, which is similar to for/first, except that it goes on to the next iteration if the body returns false.
(for/or ([ite '(1 2 3 4 5 6 7 8 9)]
#:when (equal? (check-available row col ite board) #t))
(let ([new-board (set-value board row col ite)])
(if (equal? col 8)
(solver (+ 1 row) 0 new-board boolboard)
(solver row (+ 1 col) new-board boolboard))))
That way, if filling in one number doesn't end up yielding a solution and it returns false, it can try the next number.
This solves your question about it returning #<void>. If there are more problems with your code, you should ask another question.

LISP copy function

I'm attempting to create a function that creates copies of whatever list the user puts in by the desired number of copies.
User: (copy '(A) '(7))
Output: (A A A A A A A)
(defun copy (x y)
(cond ((-1 counter)
nil)
(T
(list (cons (car x) (cdr x)))
copy
(cdr x)))
I'm attempting to set up a counter and just create a new list into the current list by decrementing the counter. So far the counter is pseudo-code.
This is the counter I'm trying to figure out.
(defun count (y)
(let ((a y))
(- a 1)))
The error I get is that whatever I put into y isn't a number.
While I can understand why the first parameter is a list, the second must be a number. A very simple implementation might look like:
(defun copy (lst count)
(when (> count 0)
(append (copy-list lst) (copy lst (1- count)))))
Testing:
CL-USER> (copy '(A) 7)
(A A A A A A A)
CL-USER> (copy '(A B C) 7)
(A B C A B C A B C A B C A B C A B C A B C)
The usual caveats concerning the use of append and object copying apply.
I'd suggest passing your list as a &rest argument instead and use loop:
(defun repeat (n &rest items)
(loop repeat n append items))
Test
CL-USER> (repeat 10 0 1 2)
(0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2)

What is the difference between a transparent and a prefab struct?

As the title implies, I don't understand the difference between using #:transparent and using #:prefab when defining a struct. The reference mentions that prefab involves some sort of global sharing.
What is the difference between them? In which situation should I use one over the other?
To make a structure type transparent, use the #:transparent keyword after the field-name sequence:
(struct posn (x y)
#:transparent)
> (posn 1 2)
(posn 1 2)
An instance of a transparent structure type prints like a call to the constructor, so that it shows the structures field values. A transparent structure type also allows reflective operations, such as struct? and struct-info, to be used on its instances.
Although a transparent structure type prints in a way that shows its content, the printed form of the structure cannot be used in an expression to get the structure back, unlike the printed form of a number, string, symbol, or list.
A prefab (“previously fabricated”) structure type is a built-in type that is known to the Racket printer and expression reader. Infinitely many such types exist, and they are indexed by name, field count, supertype, and other such details. The printed form of a prefab structure is similar to a vector, but it starts #s instead of just #, and the first element in the printed form is the prefab structure type’s name.
Lastly, I think you may need using #:transparent most of the time over #:prefab ,based on my experience I usually use #:transparent.
To extend the other answers and give some more examples for the second part of the question:
#lang racket
(struct A (x y))
(displayln (A 1 2)) ; => #<A>
(equal? (A 1 2) (A 1 2)) ; => #f
;(equal? (A 1 2) (read (open-input-string (~a (A 1 2))))) ; => ERR: bad syntax
(struct B (x y) #:transparent)
(displayln (B 3 4)) ; => #(struct:B 3 4)
(equal? (B 3 4) (B 3 4)) ; => #t
(equal? (B 3 4) (read (open-input-string (~a (B 3 4))))) ; => #f
(struct C (x y) #:prefab)
(displayln (C 5 6)) ; => #s(C 5 6)
(equal? (C 5 6) (C 5 6)) ; => #t
(equal? (C 5 6) (read (open-input-string (~a (C 5 6))))) ; => #t
Use opaque structs if you want to enforce the struct abstraction with no exceptions, i.e., the struct can only be created and inspected with the accessors.
Use transparent structs to give access to the printer and equal?.
Use prefab structs if you want to do serialization, e.g. when writing and reading from disk.
The racket guide probably has a more gentle introduction to prefab structs.
The biggest difference is that a transparent struct still requires the struct constructor to create one of them.
For example, given the following struct definition:
(struct foo (a b) #:prefab)
The following are two ways to create the exact same struct.
> (foo 1 2)
'#s(foo 1 2)
> #s(foo 1 2)
'#s(foo 1 2)
This means that any racket module can create a foo prefab struct, even without it being defined first. This makes it very useful if you want to put it in a macro, or send it to a separate instance of racket running on a different machine.
Generally, I would recommend going with #:transparent structs unless you need the full power of a #:prefab struct.
One other important detail not mentioned yet: transparent (and normal) structs are generative. This means if you define the same struct twice, values created with the first instance of the struct definition are not equal? to values created with the second definition. You can see this for yourself in a REPL session:
> (struct posn (x y) #:transparent)
> (define origin1 (posn 0 0))
> (struct posn (x y) #:transparent)
> (define origin2 (posn 0 0))
> (equal? origin1 origin2)
#f
Despite being the same definition and having the same content, the two instances are not equal?. Although the structs are transparent they are considered separate definitions for the reason Leif Anderson pointed out, just using #:transparent still requires that the only way to create the struct be with the constructor the struct form defines. Two definitions means two different constructors.
However, with prefab structures, that limitation goes away - you can create prefab structs yourself by just writing the reader form of them like #s(posn 0 0). There's no longer a reason to require all instances of the struct be created with its defined constructor, and thus no reason two different but identical struct definitions wouldn't recognize each other:
> (struct posn (x y) #:prefab)
> (define origin1 (posn 0 0))
> (struct posn (x y) #:prefab)
> (define origin2 (posn 0 0))
> (equal? origin1 origin2)
#t
> (equal? origin1 #s(posn 0 0))
#t
I am of the opinion that structs that represent just some raw data pooled together should be prefab to get free, easy, and safe serialization, structs that have restrictions on how they can be constructed should be transparent, and structs that should encapsulate some behavior and hide information should be neither transparent nor prefab. These are mere guidelines however, your mileage may vary.

If else clause or cond in Racket

I am trying to write a simple program in Racket that prints 1 if the value of a is > 1, prints 0 if the value of a = 0 and -1 if a < 0 . I wrote the following but looks like it is not taking care of the third condition. Actually, I have not included the third condition so I don't know how to check for all three conditions using 'if' clause. A little guidance is appreciated.
I am new to Racket. My program is:
#lang racket
(define a 3);
(if (> a 0)
0
1)
-1
Thanks in advance.
The function you are looking for is already defined under the name sgn.
The reason your implementation doesn't work is that it is incomplete. You want:
(if (= a 0)
0
(if (< a 0)
-1
1))
Or just the better looking:
(cond
[(negative? n) -1]
[(positive? n) 1]
[else 0])
So how you describe it you have two consequences and one alternative. I would then have used cond:
(cond ((> a 0) 1)
((= a 0) 0)
(else -1)) ; if it's not greater or equal it has to be less than
With cond each term you can expect all previous to be false, thus the last test is not needed since if it's not greater or equal it has to be less than 0. This is exactly the same as writing:
(if (> a 0)
1
(if (= a 0)
0
-1))
The main difference is that it looks slightly better with cond. If you have a need for begin (side effects) then using cond would also be beneficial since it has implicit begin:
(define seen
(let ((hash (make-hash)))
(lambda (x)
(cond ((hash-ref hash x #f) #t)
(else (hash-set! hash x #t) #f)))))
The same with if:
(define seen
(let ((hash (make-hash)))
(lambda (x)
(if (hash-ref hash x #f)
#t
(begin
(hash-set! hash x #t)
#f)))))
Its the same but I feel cond wins since it's less indentation and more flat.
I'm a beginner CS student, but we started with Racket and this is how we would make this. Also, I'm just going by exactly what you say in your question "prints 1 if the value of a is > 1, prints 0 if the value of a = 0 and -1 if a < 0"
(cond
[(> a 1) 1]
[(= a 0) 0]
[(< a 0) -1])
Something else that I might add just purely as a CS student going by class standards, when we were writing functions that used intervals we always wrote an appropriate amount of check-expects to see if anything unexpected happens. I noticed that you have something happen when a > 1, a = 0, and everything below 0 would be = -1. So if you wrote a = 1 it would return with -1 if you had put "else" for anything that wasn't >1, = 0, or <0 . I don't know what you would want to happen if a = 1, but I thought I would just throw that out for good measure.
If you were to put in a = 1 with the cond written above it would just return with "cond: all question results were false".. Oki, now I'm done.