I’m new to ACL2 theorem prover. I want to update the value of a variable based on XOR result of three variables. I think “setq” will do that for me.
(setq out (xor (xor a b) c))
However, I get this error:
ACL2 Error in TOP-LEVEL: The symbol SETQ (in package "COMMON-LISP") has neither a function nor macro definition in ACL2. Moreover, this symbol is in the main Lisp package; hence, you cannot define it in ACL2. See :DOC near-misses. Note: this error occurred in the context (SETQ OUT (XOR (XOR A B) C)).
Can't we use main Lisp functions in ACL2? Is there another way to update variable values in ACL2? I have already tried "assign", but I don't want my variable to become global.
ACL2 is an applicative programming language (in fact ACL2 stands for "A Computational Logic for Applicative Common Lisp"), so you cannot mutate values in your code; you can only bind new ones. So perhaps let or let* is what you're looking for.
Related
At the end of section 6.5 in the current SBCL manual, we have the following quote:
If your system's performance is suffering because of some construct which could in principle be compiled efficiently, but which the SBCL compiler can't in practice compile efficiently, consider writing a patch to the compiler and submitting it for inclusion in the main sources. Such code is often reasonably straightforward to write; search the sources for the string “deftransform” to find many examples (some straightforward, some less so).
I've been playing around and found the likes of sb-c::defknown and sb-c::deftransform but thus far have had little luck in successfully adding any new transforms that do anything.
Lets pretend i have the following 3 toy functions:
(defun new-+ (x y)
(+ x y))
(defun fixnum-+ (x y)
(declare (optimize (speed 3) (safety 0))
(fixnum x y))
(+ x y))
(defun string-+ (x y)
(declare (optimize (speed 3) (safety 0))
(string x y))
(concatenate 'string x y))
As a purely toy example, lets say we wanted to tell the compiler that it could transform calls to my user defined function new-+ into calls to either fixnum-+ or string-+.
The condition for the compiler transforming (new-+ x y) into (fixnum-+ x y) would be knowing that the arguments x and y are both of type fixnum, and the conditions for transforming into (string-+ x y) would be knowing that the arguments x and y are both of type string.
So the questions:
Can I actually do this?
What are the actual mechanics of doing so and generating other user based transforms/extensions?
Any reading or sources apart from manually reading through the source to discover more info regarding this?
If i can't do this using the likes of deftransform, is there any other way I could do so?
Note: I'm aware of the operations and nature of macros and generic functions in general common lisp coding, and don't consider using them an answer to this question, since I'm specifically curious about extending the SBCL internals and interacting with its compiler.
You achieve what you want in portable Common Lisp using define-compiler-macro
AFAIK reading the SBCL sources is the only way to learn how deftransform works. But before diving into SBCL sources checkout Paul Khuong's Starting to Hack on SBCL or at the very least The Python Compiler for CMU Common Lisp it links to to have an overview of how SBCL works.
I now attempt to provide a broad overview that answers my questions and may point others towards constructively investigating similar directions.
Can I actually do this?
Yes. Though depending on the specifics of how and why, you may have a choice of options available to you, and they may have variable levels of portability between Common Lisp implementations.
What are the actual mechanics of doing so and generating other user based transforms/extensions?
I answer this with respect to two possible methods that the programmer may choose to get started, and which seem most applicable.
For both examples, I reiterate that with limited reflection on the topic, i think it bad form to transform relationships between the input/output mappings of a function. I do so here for demonstration purposes only, to verify that the transformations I'm implementing are actually taking place.
I actually had quite a difficult time testing my transformations were actually happening: SBCL especially seems quite happy to optimise certain expressions and forms, there are additional pieces of information you can make available to the compiler not covered here. Additionally, there may be other transformations available, and so just because your transform isn't used, doesn't necessarily mean it isn't "working".
Environments and Define-Compiler-Macro Extensions using Common Lisp the Language 2
I was previously under the impression that DEFINE-COMPILER-MACRO was relatively limited in its abilities, working only on types connected with literal values, but this is not necessarily the case.
To demonstrate this, i use three user-defined functions and a compiler macro.
First: We will begin with a general addition function gen+ that decides at run-time to either add two numbers together, or concatenate two strings:
(defun gen+ (x y)
(if (and (numberp x)
(numberp y))
(+ x y)
(concatenate 'string x y)))
But say we know at compile time that in certain instances, only strings will be fed to this function. Let's define our specialised string addition function, and to prove its actually being used, we'll do a very bad thing stylistically and additionally concatenate the string "kapow" as well:
(defun string+ (x y)
(declare (optimize (speed 3) (safety 0))
(string x y))
(concatenate 'string x y "kapow"))
The following function is a very simple convenience function that checks an environment to establish whether the declared type of the variable bound in that environment is eq to STRING. We're using a NON-ANSI function here from Common Lisp the Language 2. In sbcl, the function VARIABLE-INFORMATION, and other cltl2 functions are available in the sb-ctlt2 package.
(defun env-stringp (symbol environment)
(eq 'string
(cdr (assoc 'type
(nth-value 2 (sb-cltl2:variable-information symbol environment))))))
Lastly, we use DEFINE-COMPILER-MACRO to generate the transformation. I've tried to name things in this code differently from other examples I've seen so that people can follow along and not get mixed up with what variable/symbol is in which scope/context. A couple of things I didn't know previously about DEFINE-COMPILER-MACRO.
The variable that immediately follows the &whole parameter is a variable which represents the form of the initial call. In our example it will be bound to the list (GEN+ A B)
arg1 is bound to the symbol A
arg2 is bound to the symbol B
The &environment parameter says that within this macro, the symbol ENV will be bound to the environment in which the macro is being evaluated. This is what lets us "kind of step back out of the macro" and check the surrounding code for declarations regarding the type of the variables represented by the symbols bound to 'ARG1' and 'ARG2'
In this definition, we tell the compiler macro that if the user has declared the parameters of GEN+ to be strings, then replace the call to (GEN+ ARG1 ARG2) with a call to (STRING+ ARG1 ARG2).
Note that because the condition of this transformation is the result of a user-defined operation on the environment, if the parameters to GEN+ are literal strings, the transformation will not be triggered, because the environment does not see that the variables have been declared strings. To do that, you would have to add another option and transformation to explicitly check the types of the values in ARG1 and ARG2 as per a traditional use of DEFINE-COMPILER-MACRO. This can be left as an exercise for the reader. But beware about the utility of doing so, because SBCL, for instance, might constant-fold your expression rather than use your transformation anyway.
(define-compiler-macro gen+ (&whole form arg1 arg2 &environment env)
(cond ((and (env-stringp arg1 env)
(env-stringp arg2 env))
`(string+ ,arg1 ,arg2))
(t form)))
Now we can test it with a simple call with type declarations:
(let ((a "bob")
(b "dole"))
(declare (string a b))
(gen+ a b))
This should return the string "bobdolekapow" as the call to GEN+ was transformed into a call to STRING+ based on the declared types of the variables A and B, not just literal types.
Using Basic (defknown)/(deftransform) Combinations with the SBCL Implementation Compiler
The previous technique is indeed potentially useful, more powerful and flexible than transforming on the types of literals, and while not standard ANSI Common Lisp, is more portable/adaptable to other implementations than the technique that follows.
A reason you might forego the former technique in preference of the one that follows, is that the former doesn't get you everything. You still had to declare the types of the variables a and b and write the user-defined function to extract the declared type information from the environment.
If you can interact directly with the SBCL compiler however, with the cost of potentially some brittle-ness and extreme non-portability, you now gain the ability to hack into the compiler itself and gain the benefits of things like type propagation: you might not need to explicitly inform the compiler of the types of A and B for it to implement your transformation.
For our example, we will implement a very basic transformation on the functions wat and string-wat, which are identical in form to our previous functions gen+ and string+.
Understand there are many more pieces of information and optimisation you can feed the SBCL compiler not covered here. And if anyone more experienced with SBCL internals wants to correct/extent anything regarding my impressions here, please comment and i'll be happy to update my answer:
First we tell the compiler about the existence and type signature of wat. We do this by calling defknown in the sb-c package and inform it that wat takes two parameters of any type: (T T) and that it returns a single value of any type: *
(sb-c:defknown wat (T T) *)
Then we define a simple transform using sb-c:deftransform, essentially saying when the two parameters fed to wat are strings, we transform the code into a call to string-wat.
(sb-c:deftransform wat ((x y) (string string) *)
`(string-wat x y))
The forms of wat and string-wat for completeness:
(defun wat (x y)
(if (and (numberp x)
(numberp y))
(+ x y)
(concatenate 'string x y)))
(defun string-wat (x y)
(declare (optimize (speed 3) (safety 0))
(string x y))
(concatenate 'string x y "watpow"))
And this time a demonstration in SBCL using bound variables but no explicit type declarations:
(let ((a (concatenate 'string "bo" "b"))
(b (concatenate 'string "dole")))
(wat a b))
And the returned string should be "bobdolewatpow".
Any reading or sources apart from manually reading through the source to discover more info regarding this?
I haven't been able to find anything much about this out there, and would say that to get much deeper, you're going to have to start trawling through some source code.
SBCL github mirror is currently available here.
User #PuercoPop has suggested background reading of Starting to Hack on SBCL and The Python Compiler for CMU Common Lisp, albeit I am including a link to a .pdf version rather than a .ps version commonly linked to.
The arguments of a function, I mean the x and the y as in
(defun my-function (x y ) body)
are sometimes also called the local variables or the local parameters or the formal parameters or even the parameters. Are all these terminologies really correct in Lisp? Is another terminology more suited?
Furthermore one says that the arguments of a functions are bound to the values of the arguments of the function that is calling. Is this terminology "bound to" correct? Or do we have to say that they will "have the value" of the arguments of the function called?
And does one say that a global symbol is "bound to a value" or "has the value"? I read in a book that this is a cause of enormous confusion. In that book it is suggested that the words "bound to" should not be used for global symbols, but should only be used for the arguments of a function. But on the other hand, the build in function boundp like in
(boundp 'x))
is used in Lisp also for global symbols. This would suggest that symbols do not "have a value" but are "bound to a value"?
Common Lisp uses this terminology:
A function has a defined list of parameters.
Evaluation of a function call adds a binding of each parameter with the corresponding value from the arguments to the current lexical environment.
Global variables have a binding in the global environment.
Reference
See Common Lisp HyperSpec (a HTML variant of the ANSI Common Lisp standard), and there the chapters on Evaluation/Compilation and the Glossary. That document describes the terminology, useful for Common Lisp. Other Lisp dialects (Emacs Lisp, ISLisp, Visual Lisp, ...) may have different terminology.
Example
(defun foo (a b)
(bar a b a b))
Above function explained in the comments:
(defun foo ; <- the name of the global function is foo
(a b) ; <- the list of parameters of the function foo
; <- in the body, a and b are bound
; in the body there is one function call form
(bar ; <- the function bar gets called
a b a b) ; <- the arguments to be evaluated
)
Is it possible to use (declare (type ...)) declarations in functions but also perform type-checking on the function arguments, in order to produce faster but still safe code?
For instance,
(defun add (x y)
(declare (type fixnum x y))
(the fixnum x y))
when called as (add 1 "a") would result in undefined behaviour, so preferably I'd like to modify it as
(defun add (x y)
(declare (type fixnum x y))
(check-type x fixnum)
(check-type y fixnum)
(the fixnum x y))
but I worry that the compiler is allowed to assume that the check-type always passes and thus omit the check.
So my question is, is the above example wrong as I expect it, and secondly, is there any common idiom* in use to achieve type-safety with optimised code?
*) I can imagine, for instance, using an optimised lambda and calling that after doing the type-checking, but I wonder if that's the most elegant way.
You can always check the types first and then enter optimized code:
(defun foo (x)
(check-type x fixnum)
(locally
(declare (fixnum x)
(optimize (safety 0)))
x))
The LOCALLY is used for local declarations.
Since you are asking:
Is it possible to use (declare (type ...)) declarations in functions but also perform type-checking on the function arguments, in order to produce faster but still safe code?
it seems to me that you are missing an important point about the type system of Common Lisp, that is that the language is not (and cannot-be) statically typed. Let's clarify this aspect.
Programming languages can be roughly classified in three broad categories:
with static type-checking: every expression or statement is
checked for type-correctness at compile time, so that type errors
can be detected during program development, and the code is more
efficient since no check for types must be done at run-time;
with dynamic type checking: every operation is checked at run time
for type correctness, so that no type-error can occur at run-time;
without type checking: type-errors can occur at run-time so that the
program can stop for error or have an undefined behaviour.
Edited
With the respect to the previous classification, the Common Lisp specification left to the implementations the burden of deciding if they want to follow the second or the third approach! Not only, but through the optimize declaration the specification lets the implementations free to change this dinamically, in the same program.
So, most implementations, at the initial optimization and safety levels, implements the second approach, enriched with the following two possibilities:
one can request to the compiler to omit run time type-checking when compiling some piece of code, typically for efficiency reasons, so that, inside that particular piece of code, and depending on the optimization and safety settings, the language can behave like the languages of the third category: this could be supported by hints through type declarations, like (declare (type fixnum x)) for variables and (the fixnum (f x)) for values;
one can insert into the code explicit type-checking tests to be performed at run-time, through check-type, so that an eventual difference in the type of the value checked will cause a “correctable error”.
Note, moreover, that different compilers can behave differently in checking types at compile times, but they can never reach the level of compilers for languages with static type checking because Common Lisp is a highly dynamical language. Consider for instance this simple case:
(defun plus1(x) (1+ x))
(defun read-and-apply-plus1()
(plus1 (read)))
in which no static type-checking can be done for the call (plus1 (read)), since the type of (read) is not known at compile time.
I am trying to write a program in Common Lisp using GNU ClISP to compile it. I would like to enter a list such as (A(B (C) ()) (D (E) (F (G) ()))) and depending on the first word print out the pre-, in-, or post-order traversal. Example:
(pre '(A(B (C)... etc))
I am having trouble putting my logic into Clisp notation. I currently have the following code:
(defun leftchild (L)(cadr L))
(defun rightchild (L)(caddr L))
(defun data (L)(car L))
(defun pre (L)(if (null L) '()((data L)(pre(leftchild L))(pre(rightchild L)))))
... similar in and post functions
I get compiling errors saying that I should use a lambda in my pre function. I think this is due to the double (( infront of data because it is expecting a command, but I am not sure what I should put there. I don't think cond would work, because that would hinder the recursive loop. Also, will data L print as it is now? The compiler did not recognize (print (data L)).
I have been working on this code for over a week now, trying to troubleshoot it myself, but I am at a loss. I would greatly appreciate it if someone could explain what I am doing incorrectly.
Another question that I have is how can I make the program prompt a line to the user to enter the (pre '(A... etc)) so that when I run the compiled file the program will run instead of giving a funcall error?
Thank you for your time.
Short answer: If you want to use if, note that you'll need a progn in order to have more than one form in the consequent and alternative cases.
Long answer – also explains how to traverse accumulating the visited nodes in a list:
I guess this is homework, so I won't give you a full solution, but your question shows that you have basically the right idea, so I'll show you an easy, idiomatic way to do this.
First, you're right: The car of an unquoted form should be a function, so basically anything like (foo ...), where foo is not a function (or macro, special form ...), and the whole thing is to be evaluated, will be an error. Note that this does not hold inside special forms and macros (like cond, for example). These can change the evaluation rules, and not everything that looks like (foo bar) has to be a form that is to be evaluated by the normal evaluation rules. The easiest example would be quote, which simply returns its argument unevaluated, so (quote (foo bar)) will not be an error.
Now, about your problem:
An easy solution would be to have an accumulator and a recursive helper function that traverses the tree, and pushes the values in the accumulator. Something like this:
(defun pre (node)
(let ((result (list)))
(labels ((rec (node)
(cond (...
...
...))))
(rec node)
(nreverse result))))
The labels just introduces a local helper function, which will do the actual recursion, and the outer let gives you an accumulator to collect the node values. This solution will return the result as a list. If you just want to print each nodes value, you don't need the accumulator or the helper function. Just print instead of pushing, and make the helper your toplevel function.
Remember, that you'll need a base case where the recursion stops. You should check for that in the cond. Then, you'll need the recursive steps for each subtree and you'll need to push the node's value to the results. The order in which you do these steps decides whether you're doing pre-, in-, or post-order traversal. Your code shows that you already understand this principle, so you'll just have to make it work in Lisp-code. You can use push to push values to result, and consp to check whether a node is a non-empty list. Since there's nothing to do for empty lists, you'll basically only need one test in the cond, but you can also explicitly check whether the node is null, as you did in your code.
In terms of scope? Actual implementation in memory? The syntax? For eg, if (let a 1) Is 'a' a variable or a symbol?
Jörg's answer points in the right direction. Let me add a bit to it.
I'll talk about Lisps that are similar to Common Lisp.
Symbols as a data structure
A symbol is a real data structure in Lisp. You can create symbols, you can use symbols, you can store symbols, you can pass symbols around and symbols can be part of larger data structures, for example lists of symbols. A symbol has a name, can have a value and can have a function value.
So you can take a symbol and set its value.
(setf (symbol-value 'foo) 42)
Usually one would write (setq foo 42), or (set 'foo 42) or (setf foo 42).
Symbols in code denoting variables
But!
(defun foo (a)
(setq a 42))
or
(let ((a 10))
(setq a 42))
In both forms above in the source code there are symbols and a is written like a symbol and using the function READ to read that source returns a symbol a in some list. But the setq operation does NOT set the symbol value of a to 42. Here the LET and the DEFUN introduce a VARIABLE a that we write with a symbol. Thus the SETQ operation then sets the variable value to 42.
Lexical binding
So, if we look at:
(defvar foo nil)
(defun bar (baz)
(setq foo 3)
(setq baz 3))
We introduce a global variable FOO.
In bar the first SETQ sets the symbol value of the global variable FOO. The second SETQ sets the local variable BAZ to 3. In both case we use the same SETQ and we write the variable as a symbol, but in the first case the FOO donates a global variable and those store values in the symbol value. In the second case BAZ denotes a local variable and how the value gets stored, we don't know. All we can do is to access the variable to get its value. In Common Lisp there is no way to take a symbol BAZ and get the local variable value. We don't have access to the local variable bindings and their values using symbols. That's a part of how lexical binding of local variables work in Common Lisp.
This leads for example to the observation, that in compiled code with no debugging information recorded, the symbol BAZ is gone. It can be a register in your processor or implemented some other way. The symbol FOO is still there, because we use it as a global variable.
Various uses of symbols
A symbol is a data type, a data structure in Lisp.
A variable is a conceptual thing. Global variables are based on symbols. Local lexical variables not.
In source code we write all kinds of names for functions, classes and variables using symbols.
There is some conceptual overlap:
(defun foo (bar) (setq bar 'baz))
In the above SOURCE code, defun, foo, bar, setq and baz are all symbols.
DEFUN is a symbol providing a macro.
FOO is a symbol providing a function.
SETQ is a symbol providing a special operator.
BAZ is a symbol used as data. Thus the quote before BAZ.
BAR is a variable. In compiled code its symbol is no longer needed.
Quoting from the Common Lisp HyperSpec:
symbol n. an object of type symbol.
variable n. a binding in the “variable” namespace.
binding n. an association between a name and that which the name denotes. (…)
Explanation time.
What Lisp calls symbols is fairly close to what many languages call variables. In a first approximation, symbols have values; when you evaluate the expression x, the value of the expression is the value of the symbol x; when you write (setq x 3), you assign a new value to x. In Lisp terminology, (setq x 3) binds the value 3 to the symbol x.
A feature of Lisp that most languages don't have is that symbols are ordinary objects (symbols are first-class objects, in programming language terminology). When you write (setq x y), the value of x becomes whatever the value of y was at the time of the assignment. But you can write (setq x 'y), in which case the value of x is the symbol y.
Conceptually speaking, there is an environment which is an association table from symbols to values. Evaluating a symbol means looking it up in the current environment. (Environments are first-class objects too, but this is beyond the scope of this answer.) A binding refers to a particular entry in an environment. However, there's an additional complication.
Most Lisp dialects have multiple namespaces, at least a namespace of variables and a namespace of functions. An environment can in fact contain multiple entries for one symbol, one entry for each namespace. A variable, strictly speaking, is an entry in an environment in the namespace of variables. In everyday Lisp terminology, a symbol is often referred to as a variable when its binding as a variable is what you're interested in.
For example, in (setq a 1) or (let ((a 1)) ...), a is a symbol. But since the constructs act on the variable binding for the symbol a, it's common to refer to a as a variable in this context.
On the other hand, in (defun a (...) ...) or (flet ((a (x) ...)) ...), a is a also symbol, but these constructs act on its function binding, so a would not be considered a variable.
In most cases, when a symbol appears unquoted in an expression, it is evaluated by looking up its variable binding. The main exception is that in a function call (foo arg1 arg2 ...), the function binding for foo is used. The value of a quoted symbol 'x or (quote x) is itself, as with any quoted expression. Of course, there are plenty of special forms where you don't need to quote a symbol, including setq, let, flet, defun, etc.
A symbol is a name for a thing. A variable is a mutable pointer to a mutable storage location.
In the code snippet you showed, both let and a are symbols. Within the scope of the let block, the symbol a denotes a variable which is currently bound to the value 1.
But the name of the thing is not the thing itself. The symbol a is not a variable. It is a name for a variable. But only in this specific context. In a different context, the name a can refer to a completely different thing.
Example: the symbol jaguar may, depending on context, denote
OSX 10.2
a gaming console
a car manufacturer
a ground attack military jet airplane
another military jet airplane
a supercomputer
an electric guitar
and a whole lot of other things
oh, did I forget something?
Lisp uses environments which are similar to maps (key -> value) but with extra built-in mechanisms for chaining environments and controlling bindings.
Now, symbols are pretty much, keys (except special form symbols), and point to a value,
ie function, integer, list, etc.
Since Common Lisp gives you a way to alter the values, i.e. with setq, symbols in some contexts
(your example) are also variables.
A symbol is a Lisp data object. A Lisp "form" means a Lisp object that is intended to be evaluated. When a symbol itself is used as a Lisp form, i.e. when you evaluate a symbol, the result is a value that is associated with that symbol. The way values are associated with symbols is a deep part of the Lisp langauge. Whether the symbol has been declared to be "special" or not greatly changes the way evaluation works.
Lexical values are denoted by symbols, but you can't manipulate those symbols as objects yourself. In my opinion, explaining anything in Lisp in terms of "pointers" or "locations" is not the best way.
Adding a side note to the above answers:
Newcomers to Lisp often are not sure exactly what symbols are for, besides being the names of variables. I think the best answer is that they are like enumeration constants, except that you don't have to declare them before using them. Of course, as others have explained, they are also objects. (This shouldn't seem strange to users of Java, in which enumeration constants are objects too.)
Symbol and variable are 2 different things.
Like in mathematic symbol is a value. And variable have the same meaning than in mathematic.
But your confusion came from the fact that symbol are the meta representation of a variable.
That is if you do
(setq a 42)
You just define a variable a. Incidentally the way common lisp store it is throw the structure of a symbol.
In common lips symbol is a structure withe different property. Each one can be access with function like symbol-name, symbol-function...
In the case of variable you can access his value via ssymbol-value
? (symbol-value 'a)
42
This is not the common case of getting the value of a.
? a
42
Note that symbols are self evaluating that mean that if you ask a symbol you get the symbol not the symbol-value
? 'a
A