I followed the directions on the Rosette website to download rosette (https://docs.racket-lang.org/rosette-guide/ch_getting-started.html). It seems that I can run this program and get an output error free.
#lang rosette/safe
; Compute the absolute value of `x`.
(define (absv x)
(if (< x 0) (- x) x))
; Define a symbolic variable called y of type integer.
(define-symbolic y integer?)
; Solve a constraint saying |y| = 5.
(solve
(assert (= (absv y) 5)))
However, when I try running this or any similar program using more than the basic racket keywords I get unclear (to me) errors.
#lang rosette
(struct plus (left right) #:transparent)
(struct mul (left right) #:transparent)
(struct square (arg) #:transparent)
(define prog (plus (square 7) 3))
(define (interpret p)
(destruct p
[(plus a b) (+ (interpret a) (interpret b))]
[(mul a b) (* (interpret a) (interpret b))]
[(square a) (expt (interpret a) 2)]
[_ p]))
(interpret prog)
This gives me an error destruct: unbound identifier in: destruct. What is going on? This code is not my own and is copy pasted from a tutorial so it should work I think. I have also tried example code copy pasted from the Rosette website and that gives similar errors. I've followed all the installation instructions and updated the environment path etc. Any help?
destruct is not provided by #lang rosette by default. You need to require it by writing:
(require rosette/lib/destruct)
after #lang rosette
Where did you find this code, by the way?
Related
I am trying to learn typed scheme/racket(?). Down below I have an example from my code:
#lang typed/racket
(: add (Real Real -> Real))
(define (add x y)
(+ x y))
I would like to implement a procedure "check" which checks if two datatypes are allowed with an operator. For example,
(check '(+ int int))
Should result in
int
But
(check '(* int (+ real int)))
Should result in something like this:
The operator '+' must have two operands of the same (numerical) type.
That is, check should take a list.
Questions:
How do I implement "check"? Firstly I though "ok, I have a list, so let's use car and cdr" to get the operator and the operands but it didn't work and I don't even know why it doesn't work. I also though about making if statements like (if (and (= x y) (or (= x int) (= y int)) and so on to make the checks but... don't think this is the right way to go.
Should I make a procedure "add" or not? Is there any other way to do this? Int the examples it looks like they are only using "+", "-" and so on. Lastly; How do I check that the input "int" is an int and then gives int as output.
I am pretty lost right now and I am sorry for my pretty vaugue questions but I would be really happy if someone could help me out to understand this.
Note: the procedure add takes real numbers and output a real number so it doesn't follow along with the example too well. But I hope you grasp the idea. Thanks :)
You're asking a fascinating question, and it doesn't have a simple answer.
The program that you're trying to write is essentially a type-checker. That is, it takes an expression, and checks to see whether the given function's domain includes the arguments it's being called with. We can write one of those, but I suspect you're going to be unsatisfied. Here, let me go write one now....
#lang typed/racket
(require typed/rackunit)
;; a type is either
;; - 'number, or
;; - (list 'fn list-of-types type)
;; examples of types
'number
'(fn (number number) number)
(define-type FnTy (List 'fn (Listof Ty) Ty))
(define-type Ty (U 'number FnTy))
;; given an expression, returns a type
;; or signals an error
(: check (Any -> Ty))
(define (check input)
(cond [(and (list? input)
(pair? input)
(symbol? (car input)))
(define fn-ty (lookup-fn-type (car input)))
(define arg-types (map check (rest input)))
(cond [(equal? (cadr fn-ty) arg-types)
(caddr fn-ty)]
[else (error 'check
"expression didn't type-check: ~v\n"
input)])]
[(number? input)
'number]
[else (raise-argument-error
'check
"well-formed expression"
0 input)]))
(: lookup-fn-type (Symbol -> FnTy))
(define (lookup-fn-type fn-name)
(match fn-name
['+ '(fn (number number) number)]
[other (raise-argument-error 'lookup-fn-type
"known function name"
0 fn-name)]))
(define TEST-INPUT '(+ 3 43))
(check-equal? (check TEST-INPUT)
'number)
(check-equal? (check '(+ (+ 3 4) 129837))
'number)
Does this answer any part of your question?
Im learning for exam of programming in lisp using DrRacket..
In presentation from lectures i found this code:
(define (f a b c)
(define delta)
(begin
(set! delta (- (* b b) (* 4 a c))
(if (>=? delta 0)
(writeln ”są pierwiastki”)
(writeln ”nie ma pierwiastków)))))
But it dont work.
DrRacket is showing:
. define: bad syntax (missing expression after identifier) in: (define delta)
Can't I set delta value later?
What is the problem?
thanks in advance
The original error message is because
(define delta)
is missing a value. Instead it should be something like:
(define delta 0)
There some other issues:
The double quotes weren't the " character and weren't recognized
by Racket.
Some parens were wrong.
Also I don't know why it was define-ing delta, then immediately
set!-ing it.
I tried to fix/simplify what you posted, and came up with the
following. But I'm not really sure what the function is supposed to
do, so I don't know if the example output is correct.
#lang racket
(define (f a b c)
(define delta (- (* b b) (* 4 a c)))
(if (>= delta 0)
(displayln "są pierwiastki")
(displayln "nie ma pierwiastków")))
;; Example output:
(f 1 2 3)
;;-> nie ma pierwiastków
(f 1 200 3)
;;-> są pierwiastki
Try this:
#lang racket
(define (f a b c)
(define delta 0)
(set! delta (- (* b b) (* 4 a c)))
(if (>= delta 0)
(displayln "są pierwiastki")
(displayln "nie ma pierwiastków")))
What was wrong with your code:
It's probably a copy-paste error, but in Scheme we delimit strings using the " character, not ” as in your code. And the last line is missing the closing ".
Although some interpreters accept a define without an initial value, the standard is that a value must be present after the variable name
A closing parenthesis is missing at the end of the set! line
The define and set! lines can be merged into a single line: (define delta (- (* b b) (* 4 a c)))
The >=? operator is not standard in Scheme, it might work in your interpreter but if possible use the standard >=
The writeln procedure is not standard in Scheme, in Racket you can substitute it for displayln
Not really an error, but you don't need to write a begin inside a procedure definition, it's implicit
In conclusion: the code in the question seems to be intended for a different interpreter, this question was tagged racket but believe me, what you have is not valid Racket code - heck, is not even standard Scheme. Make sure to use the correct interpreter, and be very alert for typos in the text.
I think Greg already has a perfect answer to your problem, but I just want to add the obvious let version of his code as well:
;; for a given ax^2+bx+c=0
;; this displays if it has at least one
;; real number answer or not
(define (equation-has-answer a b c)
(let ((delta (- (* b b) (* 4 a c))))
(if (>= delta 0)
(displayln "Has answer(s)")
(displayln "Has no answers"))))
To just make a predicate you can do this:
;; for a given ax^2+bx+c=0
;; this returns #t if it has at least one
;; real number answer and #f otherwise
(define (equation-has-answer? a b c)
(>= (- (* b b) (* 4 a c)) 0))
Let's say I have the following two files:
;; demo.scm
(define-module (demo)
#:export (f))
(define (g x) 1)
(define (f x) (g x))
... and in the same directory:
;; use-demo.scm
(add-to-load-path ".")
(use-modules (demo))
(define (g x) (+ x 1))
(display (f 5))
(newline)
Running use-demo.scm in Guile (2), I get the output 1. So it looks like the function f has 'closed over' the function g that's defined in module demo. Is there any way to get around this? I really want to use the version of g that I've redefined in use-demo.scm.
OK, just for the record, I did some research and am posting the solution to this specific problem in case it helps someone.
The trick is to not redefine g locally, but rather to 'inject' the new function into the demo module's mapping of names to values.
(add-to-load-path ".")
(use-modules (demo))
(module-define! (resolve-module '(demo)) 'g
(lambda (x) (+ x 1)))
(display (f 5))
(newline)
If you have specific functions that you'd like to be able to override, you could make them configurable using parameters. This has some advantages:
You don't need to call reload-module to put the module back in its original configuration.
The changes only apply for the scope of the code which needs the modified behaviour.
It works properly when using multiple threads.
Obviously, the main disadvantage is that you need to add some boilerplate for each function that you want to allow to be overridden (although that's what hygienic macros are for, hehe).
The following code may work. I haven't run it.
;; demo.scm
(define-module (demo)
#:export (f))
(define (default-g x) 1)
(define p (make-parameter default-g))
(define (f x) ((p) x))
;; use-demo.scm
(add-to-load-path ".")
(use-modules (demo))
(define (my-g x) (+ x 1))
(parameterize ((## (demo) p) my-g)
(display (f 5))
(newline))
Obviously, if you can provide some additional information about what the application for this capability is, I might be able to suggest alternative approaches (there are a few others).
I'm new to functional language and I'm doing SICP programming assignments using Racket.
Below is a snippet of code, and Racket informs me that define: expected only one expression for the function body, but found 5 extra parts, in line 5 ((define (y k)):
(define (simpson f a b n)
(define h (/ (- b a) n))
(define (y k)
(f (+ a (* k h))))
(define (factor k)
(cond ((or (= k 0) (= k n))
1)
((odd? k)
4)
(else
2)))
(define (term k)
(* (factor k)
(y k)))
(define (next k)
(+ k 1))
(if (not (even? n))
(error "n can't be odd")
(* (/ h 3)
(sum term (exact->inexact a) next n))))
I guess this problem is related to the language settings, but I already use "advanced" option.
Anybody know how to configure Racket properly, or internal "define" is not supported?
Indeed, it's as you say: internal defines are not supported by the Advanced language. For working with the SICP exercises, I've been told it's best to use the neil/sicp package: instructions for using this are detailed here.
However, even the standard Racket language (#lang racket) will support internal defines without problems.
I would like to include all the functions defined in a given racket file so that I get the same effect as if they were copied. Is it possible to do that?
To export the functions out of a module, you use provide, consider a file "foo.rkt":
#lang racket
(define fortytwo 42)
(define (det a b c)
(- (* b b) (* 4 a c)))
(provide (fortytwo det))
The file "bar.rkt" now can import definitions from "foo.rkt":
#lang racket
(require "foo.rkt")
(define (baz a b c)
(+ (det a b c) (- c 4)))
The other way you could allow other files to have access to everything that’s defined in the file, is using (all-defined-out):
#lang racket
(define fortytwo 42)
(define (det a b c)
(- (* b b) (* 4 a c)))
(provide (all-defined-out))
Hope that helps.
You can use include as follows:
Create a file called "foo.rkt" that looks like this:
(define x 1)
(define y 2)
Then in another file:
#lang racket
(require racket/include)
(include "foo.rkt")
(+ x y)
You should see the result 3.
You can see the documentation for include as well.
You could use load
(load "assert.scm")