Variable In- output in ACT-R Chunk - lisp

Given Unit1 standard ACTR documentary code:
(add-dm
(b ISA count-order first 1 second 2)
(c ISA count-order first 2 second 3)
(d ISA count-order first 3 second 4)
(e ISA count-order first 4 second 5)
(firstgoal ISA count-from start 0 end 5)
)
question:looking at the 0 and the 5 in den firstgoal chunk. Is it possible to declare that more generic like:
(firstgoal ISA count-from start *global_start_var* end *global_end_var*)
Is it possible to output a specific value in an chunk?
Speaking of the counter I want a code running the model and then evaluate the number which the counter model counted to
Example how a lisp code might look like with proper value infiltration in the lisp model
;; load the model
(load "counter.lisp")
;; set the start and end variables
(setvar *global_start_var* 0)
(setvar *global_start_end* 9)
;; run the model
(run 9999)
;; safe the result of the counter in the (local) variable result using the function get_val
(result (get_val))

To set the chunk contents using Lisp variables you can use the add-dm-fct function which takes a list of chunk description lists:
(add-dm-fct (list (list 'firstgoal 'ISA 'count-from 'start *global_start_var* 'end *global_end_var*)))
To get the current value from the slot of a chunk you need to use the macro chunk-slot-value or the function chunk-slot-value-fct. Those both take two parameters: the name of the chunk and the name of the slot, and then return the value of that slot in that chunk.
With the chunks you've shown there, this:
(chunk-slot-value b first)
will return 1.

Related

Processing raw binary data with Racket

I am new to Racket Lang and previously I wrote thousands of lines of code in C++, Java and C. I am trying to figure out how to do the following task:
Given an array (like C uint8_t array) with the following format:
First byte is used to indicate the "format", let's say this could be 0x0a, 0x0b and so on.
Remaining data may include C strings without the null terminator and integers.
Write a function that parses the array and puts the values in some variables.
Before asking here, I was reading: https://docs.racket-lang.org/guide and also https://docs.racket-lang.org/reference
My approach is as follows:
I am using a byte string because it seems it can be used to mimic the C++/C arrays.
I am using tail recursion to traverse the "array".
Questions:
1) In C, I always use the return value of a function as an error code: 0 is ok and any negative value is an error. With Racket, I am using multiple return values to indicate: a) the return code, b) the processed value(s), i.e. something like:
(values return_code out1 out2 ...)
What do you think? Do you recommend the use of exceptions for error handling?
2) What's the best approach to process arrays in Racket? I mean, the best according to the offered by Racket and to achieve a good performance.
Thanks!
Edit1:
Regarding my first question (the return codes), I am calling many functions and I would like to return an exit code that helps me to know if there was an error inside the function. This is a sample code:
#lang racket
(define (is_valid in)
(cond
[(and (>= in 10) (<= in 15)) #t]
[else #f]))
(define (copy_values in)
(define len (bytes-ref in 2))
; 3 is where the string "ABCD" begins
(define str (subbytes in 3 (+ 3 len)))
(define numbers (subbytes in (+ 3 len)))
(values str numbers))
(define (parse in)
(define type (bytes-ref in 0))
(if (is_valid type)
(let ()
(define-values (str numbers) (copy_values in))
(values #t str numbers))
(values #f 0 0)))
; format: type strlen
; len |-- str --| | -- numbers -- |
;
(define input1 (bytes 10 10 4 65 66 67 68 110 120 130 140 150))
(define input2 (bytes 1 10 4 65 66 67 68 110 120 130 140 150))
(parse input1)
(parse input2)
This is the output in DrRacket:
Welcome to DrRacket, version 6.7 [3m].
Language: racket, with debugging; memory limit: 128 MB.
#t
#"ABCD"
#"nx\202\214\226"
#f
0
0
Look how I use the (values ...) stuff, does that make sense?
To return a value to the operating system, use (exit [v]).. Other values should probably go to standard out and/or standard error. This means writing them before the program exits.
In terms of assigning the values of an array to variables, there are many ways to do it depending on how lexical scope comes into play within the function and module and across modules. Also reference semantics versus value semantics are considerations.
Finally, there is no compelling reason to choose recursion over an explicit loop when dealing with a byte-string. bytes-length is a low level primitive implemented in C and will return the length needed for a loop without testing for an empty byte-string.

Accessing a nested structure slot

I have the following structures:
(defstruct track
size
env
startpos
endpositions)
(defstruct state
pos
vel
action
cost
track
other)
I have a state and Im trying to access endpositions(list of lists)
(setq coluna_final (nth 1 (nth 0 (state-track-endpositions st))))
but I get the error: EVAL: undefined function STATE-TRACK-ENDPOSITIONS
What am I doing wrong?
The first defstruct defines (inter alia) function track-endpositions, and the second defines state-track. Lisp has no way to know that the latter returns a track (even if you declare the slot type, it will not define the function you want).
You can do it yourself:
(defun state-track-endpositions (st)
(track-endpositions (state-track st)))

How to create a Lisp FLI function corresponding to a C macro

I want to create a lisp function which corresponds to a macro in C.
e.g., there is one HIWORD in win32 API, which is defined as a macro in the header file.
I tried to define it as below but was told that HIWORD is unresolved.
CL-USER 4 > (hiword #xFFFFFFFF)
Error: Foreign function HIWORD trying to call to unresolved external function "HIWORDW".
I just want to know how to create a wrapper for C macros like for C functions.
(fli:define-c-typedef DWORD (:unsigned :long))
(fli:define-c-typedef WORD (:unsigned :short))
(fli:define-foreign-function
(HIWORD "HIWORD" :dbcs)
((dwVal dword))
:result-type word :calling-convention :stdcall)
You cannot do this directly. C preprocessor macros are not preserved in the compilation process, i.e., there is simply no artifact in the generated object files, which would correspond to the C macro itself (though its expansion may be part of the object file multiple times). And since there is no artifact, there is nothing to bind to with FFI.
You can, however, provide a wrapper function
#define HIGHWORD(x) /* whatever */
int
highword_wrapper(int x)
{
return HIGHWORD(x);
}
and this one can be used with FFI.
No need to jump into another language. Shifting and masking in Lisp:
(defun hiword (val)
(logand (ash val -16) #xFFFF)
(defun loword (val) ;; ditto
(logand val #xFFFF))
Another way: using the ldb accessor with ranges expressed using byte syntax:
(defun hiword (val)
(ldb (byte 16 16) val) ;; get 16-bit-wide "byte" starting at bit 16.
(defun loword (val)
(ldb (byte 16 0) val) ;; get 16-bit-wide "byte" at position 0.

Two simple push functions; one permanently mutates global var, other doesn't, why?

Here are two simple functions that use push on a variable passed in:
(defun push-rest (var) (push 99 (rest var)))
and
(defun just-push (something) (push 5 something))
The first one will permanently mutate the var passed. The second does not. This is quite confusing for someone who is learning the scoping behavior of this language:
CL-USER> (defparameter something (list 1 2))
SOMETHING
CL-USER> something
(1 2)
CL-USER> (just-push something)
(5 1 2)
CL-USER> something
(1 2)
CL-USER> (push-rest something)
(99 2)
CL-USER> something
(1 99 2)
In push-rest why isn't the var's scope local to the function like in just-push, when they are both using the same function, push?
According to Peter Siebel's Practical Common Lisp, Chapter 6. Variables: This might help you a lot:
As with all Common Lisp variables, function parameters hold object references. Thus, you can assign a new value to a function parameter within the body of the function, and it will not affect the bindings created for another call to the same function. But if the object passed to a function is mutable and you change it in the function, the changes will be visible to the caller since both the caller and the callee will be referencing the same object.
And a footnote:
In compiler-writer terms Common Lisp functions are "pass-by-value." However, the values that are passed are references to objects.
(Pass by value also essentially means copy; but we aren't copying the object; we are copying the reference/pointer to the object.)
As I noted in another comment:
Lisp doesn't pass objects. Lisp passes copies of object references to functions. Or you could think of them as pointers. setf assigns a new pointer created by the function to something else. The previous pointer/binding is not touched. But if the function instead operates on this pointer, rather than setting it, then it operates on the original object the pointer points too. if you are a C++ guy, this might make much more sense for you.
You can't push on a variable passed. Lisp does not pass variables.
Lisp passes objects.
You need to understand evaluation.
(just-push something)
Lisp sees that just-push is a function.
Now it evaluates something. The value of something is a list (1 2).
Then it calls just-push with the single argument (1 2).
just-push will never see the variable, it does not care. All it gets are objects.
(defun push-rest (some-list) (push 99 (rest some-list)))
Above pushes 99 onto the rest, a cons, of the list passed. Since that cons is visible outside, the change is visible outside.
(defun just-push (something) (push 5 something))
Above pushes 5 to the list pointed to by something. Since something is not visible outside and no other change has made, that change is not visible outside.
push works differently when it's passed a symbol or list as it's second argument. Pehaps you might understand it better if you do macroexpand on the two different.
(macroexpand '(push 99 (rest var)))
;;==>
(let* ((#:g5374 99))
(let* ((#:temp-5373 var))
(let* ((#:g5375 (rest #:temp-5373)))
(system::%rplacd #:temp-5373 (cons #:g5374 #:g5375)))))
Now most of this is to not evaluate the arguments more than once so we can in this case rewrite it to:
(rplacd var (cons 99 (rest var)))
Now this mutates the cdr of var such that every binding to the same value or lists that has the same object in it's structure gets altered. Now lets try the other one:
(macroexpand '(push 5 something))
; ==>
(setq something (cons 5 something))
Here is creates a new list starting with 5 and alters the local functions binding something to that value, that in the beginning pointed to the original structure. If you have the original structure in a variable lst it won't get changed since it's a completely different binding than something. You can fix your problem with a macro:
(defmacro just-push (lst)
(if (symbolp lst)
`(push 5 ,lst)
(error "macro-argument-not-symbol")))
This only accepts variables as argument and mutates it to a new list having 5 as it's first element and the original list as it's tail. (just-push x) is just an abbreviation for (push 5 x).
Just to be clear. In an Algol dialect the equivalent code would be something like:
public class Node
{
private int value;
private Node next;
public Node(int value, Node next)
{
this.value = value;
this.next = next;
}
public static void pushRest(Node var)
{
Node n = new Node(99, var.next); // a new node with 99 and chained with the rest of var
var.next = n; // argument gets mutated to have new node as next
}
public static void justPush(Node var)
{
var = new Node(5, var); // overwrite var
System.out.print("var in justPush is: ");
var.print();
}
public void print()
{
System.out.print(String.valueOf(value) + " ");
if ( next == null )
System.out.println();
else
next.print();
}
public static void main (String[] args)
{
Node n = new Node( 10, new Node(20, null));
n.print(); // displays "10 20"
pushRest(n); // mutates list
n.print(); // displays "10 99 20"
justPush(n); // displays "var in justPush is :5 10 99 20"
n.print(); // displays "10 99 20"
}
}
(push item place)
It work as follows when the form is used to instruct the place where this is referred to in the setf:
(setf place (cons item place))
Basedon your profile, it looks like you have familiarity with C-like languages. push is a macro, and is the following equivalence is roughly true (except for the fact that this would cause x to be evaluated twice, whereas push won't):
(push x y) === (setf x (list* x y))
That's almost a C macro. Consider a similar incf macro (CL actually defines an incf, but that's not important now):
(incf x) === (setf x (+ 1 x))
In C, if you do something like
void bar( int *xs ) {
xs[0] = xs[0] + 1; /* INCF( xs[0] ) */
}
void foo( int x ) {
x = x + 1; /* INCF( x ) */
}
and have calls like
bar(zs); /* where zs[0] is 10 */
printf( "%d", zs[0] ); /* 11, not 10 */
foo(z); /* where z is 10 */
printf( "%d", z ); /* 10, not 11 */
The same thing is happening in the Lisp code. In your first code example, you're modifying contents of some structure. In your second code example, you're modifying the value of lexical variable. The first you'll see across function calls, because the structure is preserved across function calls. The second you won't see, because the lexical variable only has lexical scope.
Sometimes I wonder if Lisp aficionados (myself included) promote the idea that Lisp is different so much that we confuse people into thinking that nothing's the same.

Are the variables *,+, and / bound to recent input in SLIME or Clozure CL?

I was messing around in SLIME (connected a Clozure REPL) when I discovered this:
It looks like the variables +, *, and / are all bound to some variation on recent input, + is the input itself, * is the result of evaluating that input, and / is the result contained in a list.
Is this right? Who is responsible for this, SLIME or Clozure? I couldn't find anything in the SLIME manual.
Thanks!
; SLIME 2010-05-13
CL-USER> +
NIL
CL-USER> *
NIL
CL-USER> /
(NIL)
CL-USER> -
-
CL-USER> +
-
CL-USER> (list 1 2)
(1 2)
CL-USER> +
(LIST 1 2)
CL-USER> /
((LIST 1 2))
CL-USER> (+ 1 2)
3
CL-USER> /
(3)
CL-USER> *
(3)
CL-USER> (* 1 2)
2
CL-USER> *
2
CL-USER>
Those are all, and more, specified by the Common Lisp standard. Search the environment dictionary for 'Variable'.
+
++
+++
While a form is being evaluated by the top-level loop, the variable + is bound to the previous form read by the loop. The variable ++ holds the previous value of + (that is, the form evaluated two interactions ago), and +++ holds the previous value of ++.
-
While a form is being evaluated by the top-level loop, the variable - is bound to the form itself; that is, it is the value about to be given to + once this interaction is done.
*
**
***
While a form is being evaluated by the top-level loop, the variable * is bound to the result printed at the end of the last time through the loop; that is, it is the value produced by evaluating the form in +. If several values were produced, * contains the first value only; * contains nil if zero values were produced. The variable ** holds the previous value of * (that is, the result printed two interactions ago), and * holds the previous value of **.
/
//
///
While a form is being evaluated by the top-level loop, the variable / is bound to a list of the results printed at the end of the last time through the loop; that is, it is a list of all values produced by evaluating the form in +. The value of * should always be the same as the car of the value of /. The variable // holds the previous value of / (that is, the results printed two interactions ago), and /// holds the previous value of //. Therefore the value of ** should always be the same as the car of //, and similarly for * and ///.
From Common Lisp the Language, 2nd Edition 20.2