I am learning Racket for an Artificial Intelligence class. For the first project, the teacher gave us a file with contracts and unit tests, we are to code the functions required to make it run. I just created stubs of the functions I will need and met all the contracts except one:
[start-state (and/c state? (not/c state-game-over?))]
The function I declared looks like this at the moment:
(define (start-state)
(state '() start-tiles 0)
)
And the state struct was given by the teacher:
(struct state (played unplayed passes) #:prefab)
With contract:
[struct state ((played (listof (and/c tile? tile-at-origin?)))
(unplayed (listof (and/c tile? tile-on-board?)))
(passes pass-count?))]
This crashes with error:
start-state: broke its contract
promised: (and/c state? (not/c state-game-over?))
produced: #<procedure:start-state>
which isn't: state?
in: (and/c state? (not/c state-game-over?))
contract from:
I believe my start-state procedure creates and returns a state struct, but apparently it returns itself and violates the contract. How do I return the struct and not the procedure?
It looks like start-state isn't supposed to be a procedure, but a value. That is, you need to do
(define start-state (start ...))
instead of
(define (start-state) ...)
Related
I have a signature for representing software programs:
sig Program {
???: Data -> Result
}
Each program maps input data to output result. So, there is a ternary relation (Program -> Data -> Result).
Notice the question marks for the field name. What field name do you suggest?
The name IO seems nice:
sig Program {
IO: Data -> Result
}
Then I can write elegant expressions such as:
all p: Program | p.IO ...
However, the name IO is meaningful only for (Data -> Result) not (Program -> Data -> Result).
I am stuck. What do you suggest?
IMHO, fields' names are most of the time contextual to the signature they are declared in, and that's really a fine thing.
If you look at a random sample module in Alloy, (e.g. module examples/puzzle/farmer), you'll see that it's not always that fields have meaning outside of their respective signatures:
sig State {
near: set Object,
far: set Object
}
Here, near and far don't really convey hints on their "temporal" nature.
Long story short, I'd stick to io for conciseness sake.
Indeed, I prefer the names of :
fiels, facts, preds, asserts, parameters, .. to be in lowercase
signatures to be Capitalized
enumeration (outer let), and singleton signatures to be in UPPERCASE
Consider the make-account procedure in SICP.
(define (make-account balance)
(define (withdraw amount)
(if (>= balance amount)
(begin
(set! balance (- balance amount))
balance)
"Insufficient funds"))
(define (deposit amount)
(set! balance (+ balance amount))
balance)
(define (dispatch m)
(cond ((eq? m 'withdraw) withdraw)
((eq? m 'deposit) deposit)
(else (error "Unknown request: MAKE-ACCOUNT" m))))
dispatch)
And the example:
(define peter-acc (make-account 100))
(define paul-acc peter-acc)
And the footnote:
The phenomenon of a single computational object being accessed by more
than one name is known as aliasing. The joint bank account situation
illustrates a very simple example of an alias. ... Bugs can
occur in our programs if we forget that a change to an object may
also, as a “side effect,” change a “different” object because the two
“different” objects are actually a single object appearing under
different aliases. These so-called side-effect bugs are so difficult
to locate and to analyze that some people have proposed that
programming languages be designed in such a way as to not allow side
effects or aliasing ..."
In normal situations, I would here people say: "paul-acc refers to peter-acc".
As I understand it, peter-acc and paul-acc are really names that point to one computational object. So they are the same.
I am confused as to how it would be modeled in the environment model of evaluation. For example:
(define (f bank-account) ((bank-account 'deposit) 69))
(define peter-acc (make-account 100))
(define paul-acc peter-acc)
(f paul-acc)
I cannot do environment diagrams because my eyes are destroyed. Here's what I think the interaction should be:
make-account and f have pointers to the global environment.
(define peter-acc (make-account 100)) is evaluated. make-account creates a new environment e1. Enclosing environment is global. The internal procedures withdraw, deposit and dispatch are created and have pointers to e1. Dispatch is returned and is bound to the name peter-acc in the global environment.
(define paul-acc peter-acc) is evaluated. The name peter-acc is found in the global frame. paul-acc is bound to the dispatch procedure object in e1 because that is where peter-acc is pointing to. Therefore, Dispatch in e1 is bound to the names peter-acc and paul-acc in the global environment.
(f paul-acc) is evaluated. A new environment e2 is created by f. Enclosing environment is global. paul-acc is found in global. In e2, banck-account is bound to the dispatch procedure object in e1 because that is where paul-acc is pointing to. Therefore, peter-acc with respect to the global environment, paul-acc with respect to the global environment, and bank-acount with respect to e2 all point to the dispatch procedure in e1.
The body gets executed.
Is this all correct?
The thing that confuses me is when I encounter things like this in SICP exercises, when constructing environment diagrams, I read people on the web saying things like "bank-account refers to paul-acc. Paul-acc refers to peter-acc." Why exactly is the word "refers" used here? Does bank-account with respect to e2 actually point to the name paul-acc and not it's value?
Your points 2 to 5 are correct. In your point 1, f and make-account do not "have" pointers to global environment - they do not need to, by themselves. They are both entries, bindings, in the global environment. Both "refer to", or "point at" simple values, functions in both cases.
bank-account with respect to e2 actually points to the value to which paul-acc points (which is the same value to which peter-acc points, or refers). In Scheme, (define n1 n2) means "set up new binding in the current environment, named n1, and pointing at the value of the expression n2". If n2 happens to be a variable, its value is just what that variable's value is. That's why we're talking about Scheme's evaluation semantics.
A function call (fun arg) is evaluated by finding the value of arg expression, binding the function's parameter to this value, and then evaluating the function's body in the resulting environment:
( (lambda (param) body) arg )
=
(let ( (param arg) )
body)
Suppose I have some function which returns a struct:
(struct layer (points lines areas))
(define (build-new-layer height)
...
(layer list-a list-b list-c))
I want to keep track of the last returned result something like:
(define top-side (build-new-layer 0)) ; store the first result
...
(set! top-side (build-new-layer 0.5)) ; throw away the first result and store the new one
However, for that particular code I get the error:
set!: assignment disallowed;
cannot modify a constant
constant: top-side
Please, tell me what would be the right way to do what I want
What language are you using? it seems it's a matter of configuration, because in principle what you're doing should work. Go to the "choose language" window (Ctrl+L in Windows), click on "show details" and see if one of the options of the language currently in use disallows redefinition of variables. Alternatively, try using a different language.
Depending on where exactly you're going to use the stored result (I can't tell from the code in the question), you could pass it around as function parameters, in such a way that using a global variable is no longer necessary. This might be a better idea, relying on global state and mutation (the set! operation) is discouraged in Scheme.
If you always want to keep around the last layer, then you might prefer setting the last-layer every time one is built. Like this.
(define last-layer #f)
(define build-new-layer
(let ((save-layer #f))
(lambda (height)
(let ((new-layer (layer list-a ...)))
(set! last-layer save-layer)
(set! save-layer new-layer)
new-layer))))
Note: if the real problem is the 'constant-ness' of last-layer then build yourself a little abstraction as:
(define-values (last-layer-get last-layer-set!)
(begin
(define last-layer-access
(let ((last-layer #f))
(lambda (type . layer)
(case type
((get) last-layer)
((set) (set! last-layer (car layer)))))))
(values (lambda () (last-layer-access 'get))
(lambda (layer) (last-layer-access 'set layer))))
I'm looking to call functions dynamically based on the contents found in an association list.
Here is an example in semi-pseudo-code. listOfFunctions would be passed to callFunctions.
listOfFunctions = [('function one', 'value one')
, ('function two', 'value two')
, ('function three', 'value three')]
callFunctions x = loop through functions
if entry found
then call function with value
else do nothing
The crux of the question is not looping through the list, rather, it's how to call a function once I have it's name?
Consider this use case for further clarification. You open the command prompt and are presented with the following menu.
1: Write new vHost file
2: Exit
You write the new vHost file and are not presented with a new menu
1: Enter new directive
2: Write file
3: Exit
You enter some new directives for the vHost and are now ready to write the file.
The program isn't going to blindly write each and every directive it can, rather, it will only write the ones that you supplied. This is where the association list comes in. Writing a giant if/then/else or case statement is madness. It would be much more elegant to loop through the list, look for which directives were added and call the functions to write them accordingly.
Hence, loop, find a function name, call said function with supplied value.
Thanks to anyone who can help out with this.
Edit:
Here is the solution that I've come up with (constructive critiques are always welcome).
I exported the functions which write the directives in an association list as every answer provided said that just including the function is the way to go.
funcMap = [("writeServerName", writeServerName)
,("writeServeralias", writeServerAlias)
,("writeDocRoot", writeDocRoot)
,("writeLogLevel", writeErrorLog)
,("writeErrorPipe", writeErrorPipe)
,("writeVhostOpen", writeVhostOpen)]
In the file which actually writes the hosts, that file is imported.
I have an association list called hostInfo to simulate some dummy value that would be gathered from an end-user and a function called runFunction which uses the technique supplied by edalorzo to filter through both the lists. By matching on the keys of both lists I ensure that the right function is called with the right value.
import Vhost.Directive
hostInfo = [("writeVhostOpen", "localhost:80")
,("writeServerName", "norics.com")]
runFunctions = [f val | (mapKey, f) <- funcMap, (key, val) <- hostInfo, mapKey == key]
You can simply include the function in the list directly; functions are values, so you can reference them by name in a list. Once you've got them out of the list, applying them is just as simple as func value. There's no need to involve their names at all.
Since I am farily new to Haskell I will risk that you consider my suggestion very naive, but anyways here it goes:
let funcs = [("sum", (+3),1),("product", (*3),2),("square", (^2),4)]
[f x | (name, f, x) <- funcs, name == "sum"]
I think it satisfies the requirements of the question, but perhaps what you intend is more sofisticated than what I can see with my yet limitted knowledge of Haskell.
It might be a bit of an overkill (I agree with ehird's reasoning) but you can evaluate a string with Haskell code by using the eval function in System.Eval.Haskell.
EDIT
As pointed out in the comments, hint is a better option for evaluating strings with Haskell expressions. Quoting the page:
This library defines an Interpreter monad. It allows to load Haskell modules, browse them, type-check and evaluate strings with Haskell expressions and even coerce them into values. The library is thread-safe and type-safe (even the coercion of expressions to values). It is, esentially, a huge subset of the GHC API wrapped in a simpler API. Works with GHC 6.10.x and 6.8.x
First we define our list of functions. This could be built using more machinery, but for the sake of example I just make one explicit list:
listOfFunctions :: [(Int, IO ())]
listOfFunctions = [(0, print "HI") -- notice the anonymous function
,(1, someNamedFunction) -- and something more traditional here
]
someNamedFunction = getChar >>= \x -> print x >> print x
Then we can select from this list however we want and execute the function:
executeFunctionWithVal :: Int -> IO ()
executeFunctionWithVal v = fromMaybe (return ()) (lookup v listOfFunctions)
and it works (if you import Data.Maybe):
Ok, modules loaded: Main.
> executeFunctionWithVal 0
"HI"
> executeFunctionWithVal 01
a'a'
'a'
Don't store the functions as strings, or rather, try storing the actual functions and then tagging them with a string. That way you can just call the function directly. Functions are first class values, so you can call the function using whatever name you assign it to.
In Common Lisp, how can I override the default string representation of a CLOS class so that calls to format or princ will print something intelligible, even when objects of that class are embedded within other types, such as lists or arrays?
For example, if I call (format t "~a~%" x) when x holds an instance of my solution class, I want it to print something like #<SOLUTION genes: #(1 2 3) scores: #(4 5) rank: 6> instead of #<SOLUTION {BB7CD31}>.
So far, all I have managed to figure out is writing custom functions to handle printing structures that I know will contain instances of this class, but this is tedious. Surely Lisp provides some way to get this functionality for free?
You should be looking at print-object and print-unreadable-object. Suppose you have a class named FOO like so:
(defclass foo ()
((name :accessor foo-name)))
And you want to print instances like this: #<FOO "xyz"> where "xyz" is the content of slot name. In this case, the following implementation of print-object would do what you want:
(defmethod print-object ((obj foo) out)
(print-unreadable-object (obj out :type t)
(format out "~s" (foo-name obj))))
Check out print-object.
If you also look 22.1.3.13 Printing Other Objects it suggests print-unreadable-object as a common format macro for such situations