• Top
    • Documentation
    • Books
    • Recursion-and-induction
    • Boolean-reasoning
    • Debugging
    • Projects
    • Std
    • Proof-automation
    • Macro-libraries
    • ACL2
      • Theories
      • Rule-classes
      • Proof-builder
      • Hons-and-memoization
      • Events
      • History
      • Parallelism
      • Programming
        • Defun
        • Declare
        • System-utilities
        • Stobj
        • State
        • Memoize
        • Mbe
        • Io
        • Defpkg
        • Apply$
        • Mutual-recursion
        • Loop$
        • Programming-with-state
        • Arrays
        • Characters
        • Time$
        • Loop$-primer
        • Fast-alists
        • Defmacro
        • Defconst
        • Evaluation
        • Guard
        • Equality-variants
        • Compilation
        • Hons
        • ACL2-built-ins
        • Developers-guide
        • System-attachments
        • Advanced-features
        • Set-check-invariant-risk
        • Numbers
        • Irrelevant-formals
        • Efficiency
        • Introduction-to-programming-in-ACL2-for-those-who-know-lisp
          • Redefining-programs
          • Lists
          • Invariant-risk
          • Errors
          • Defabbrev
          • Conses
          • Alists
          • Set-register-invariant-risk
          • Strings
          • Program-wrapper
          • Get-internal-time
          • Basics
          • Packages
          • Defmacro-untouchable
          • Primitive
          • <<
          • Revert-world
          • Set-duplicate-keys-action
          • Unmemoize
          • Symbols
          • Def-list-constructor
          • Easy-simplify-term
          • Defiteration
          • Defopen
          • Sleep
        • Start-here
        • Real
        • Debugging
        • Miscellaneous
        • Output-controls
        • Macros
        • Interfacing-tools
      • Interfacing-tools
      • Hardware-verification
      • Software-verification
      • Testing-utilities
      • Math
    • Programming
    • Introduction-to-the-theorem-prover

    Introduction-to-programming-in-ACL2-for-those-who-know-lisp

    Introduction to programming in ACL2 for Lisp users

    The documentation topic, ACL2-built-ins, as well as its parent topic, programming, are starting points for a rich collection of primitives and features in the ACL2 programming language. In the present topic (below) we give a succinct introduction to that language for those who are already reasonably familiar with Common Lisp, or perhaps another Lisp. Follow the hyperlinks if you want to drill down; for example, we mention multiple values below but say very little about them, instead providing links to topics that explain their handling in a little more depth.

    The documentation for ACL2 and its community-books provides a rich set of topics for further exploration. This particular topic is intended to serve only as a brief introduction to programming in ACL2 for those who know Lisp, especially Common Lisp. Supplementary reading that may interest a few readers includes ``A Precise Description of the ACL2 Logic'' (Matt Kaufmann and J Moore, April, 1998).

    Applicative Common Lisp

    The ACL2 (``A Computational Logic for Applicative Common Lisp'') programming language is essentially a subset of Common Lisp — albeit with some useful extensions — that is applicative: the value returned by a function depends only on its inputs, not state. (There is an ACL2 notion of state, introduced briefly below; but that state must be passed as an explicit argument.) Many commonly-used functions and special forms in the applicative subset of Common Lisp are also in ACL2, such as (to name just a very few) car, cons, nth, append, let, and let*. A few others are not directly included in ACL2 because they have incomplete specifications in Common Lisp, such as pairlis; according to the Common Lisp HyperSpec: ``The new pairs may appear in the resulting association list in either forward or backward order.'' Many such functions tend to have close analogues in ACL2, named by concatenating "$" to the Common Lisp name; for example, ACL2 has pairlis$, union$, and even random$. Yet other Common Lisp functions, for example format, are not available in ACL2 but have useful alternatives in ACL2; for example, see fmt. See ACL2-built-ins for a much more comprehensive list of functions, macros, and special forms provided by the ACL2 programming language. In particular, a search through that documentation topic for `$' will show you utilities like pairlis$ that are based on related Common Lisp utilities.

    In the ACL2 read-eval-print loop, you can define functions and macros with defun and defmacro just as in Common Lisp, with some restrictions (see for example name) and also some additional declare forms.

    Data types

    Only certain Lisp data types are supported for programming in ACL2: numbers that are either rational numbers or complex numbers with rational coefficients (see numbers-introduction); the characters constructed with (code-char n) for n from 0 to 255; strings formed from those characters; symbols whose symbol-name and symbol-package-name are ACL2 strings; and objects constructed from others using cons.

    In particular, arrays are not directly supported as an ACL2 datatype (except for strings). However, ACL2 supports an applicative notion of array, which is logically an association list but has an associated Lisp array that provides fast reads in single-threaded programs. See arrays. If your code creates an array and does many more reads to it than writes, or even if there are rarely two writes to the same index (as when writes are primarily to initialize the array), then ACL2 arrays may perform well. Otherwise you may get significantly better performance, avoiding the consing done by writes (to build the association list), by using a different sort of representation of arrays in ACL2: single-threaded objects, or stobjs; see stobj.

    Structures can be simulated in ACL2 using suitable macros. For a simple such macro that is built into ACL2, together with alternatives to it, see defrec.

    Program and logic modes

    If you are using ACL2 as a programming language but you do not intend to prove anything about your code, at least not at first, then you might be well-served by using program mode. In this mode, ACL2 will admit the definition if syntactic checks succeed, in particular without requiring a proof of termination for recursive definitions. You can specify the mode directly in a declaration (see xargs for how to specify :program in a declare form), or you can set the default defun-mode to :program (see default-defun-mode and see program).

    When you are ready to reason about your functions, you can use :logic mode instead, or you can convert a program-mode function to logic-mode with verify-termination.

    Connection to Common Lisp

    Many Common Lisp functions should only be applied to certain types of objects: for example, car should only be applied to a cons pair or nil. Every ACL2 function has a guard, which specifies the intended domain of the function; see guard. For example, the guard for car is (OR (CONSP X) (EQUAL X NIL)). See args for a utility that provides this and other information about a given function symbol.

    Beginning ACL2 programmers should probably ignore guards, at least initially. Otherwise, see xargs for how to specify a guard; also see verify-guards.

    Multiple values

    The analogues of Common Lisp utilities multiple-value-bind and values are mv-let and mv, respectively. Also see b* for an alternative to let* that can be convenient in the presence of multiple values.

    State

    ACL2 provides a notion of state that is useful for certain kinds of programming. As mentioned above, the state must be passed explicitly because of the applicative nature of ACL2; indeed, it must be passed as the variable, state, i.e., the symbol in the "ACL2" package whose symbol-name is "STATE". This is a rather complex notion, perhaps best avoided by beginning ACL2 programmers. To learn about the ACL2 state, see state, which points to a topic, programming-with-state, that discusses many utilities for reading and writing the ACL2 state.

    More help

    ACL2 does not provide apropos. However, you can search the documentation to find substring matches. For example, if you type princ into the ``Jump to'' box in the web-based manual, or if you type the command i [for ''index''] into the ACL2-doc Emacs-based documentation browser, you will find princ$. The ``Jump to'' box in the web-based manual matches on prefixes, but the i command in ACL2-doc matches on any substring.

    Another way for Lisp programmers to get answers to ``How do I do this in ACL2'' questions is to query the acl2-help mailing list. You can sign up via a link on the ACL2 home page. Moreover, that could be a good place to request or suggest improvements to this documentation topic! Also see history for some ways to query the current session.

    Finally, here are a few specific alternatives to Common Lisp utilities.

    • describe: see doc
    • fboundp and other utilities to provide information about functions, macros, and special operators: see args
    • format: see fmt, which has links to related functions that perform formatted printing
    • list-all-packages: see in-package; also see the description of known-package-alist in system-utilities
    • setq: see assign, but perhaps first look at the documentation topics for state and programming-with-state
    • symbol-plist: see props, getprop, and putprop
    • with-open-file: see io