• Top
    • Documentation
    • Books
    • Boolean-reasoning
    • Projects
    • Debugging
    • Std
    • Proof-automation
    • Macro-libraries
    • ACL2
      • Theories
      • Rule-classes
      • Proof-builder
      • Recursion-and-induction
      • Hons-and-memoization
      • Events
      • Parallelism
      • History
      • Programming
        • Defun
        • Declare
        • System-utilities
        • Stobj
        • State
          • World
          • Io
          • Wormhole
          • Programming-with-state
          • W
          • Set-state-ok
          • Random$
        • Mutual-recursion
        • Memoize
        • Mbe
        • Io
        • Defpkg
        • Apply$
        • Loop$
        • Programming-with-state
        • Arrays
        • Characters
        • Time$
        • Defmacro
        • Loop$-primer
        • Fast-alists
        • Defconst
        • Evaluation
        • Guard
        • Equality-variants
        • Compilation
        • Hons
        • ACL2-built-ins
        • Developers-guide
        • System-attachments
        • Advanced-features
        • Set-check-invariant-risk
        • Numbers
        • Efficiency
        • Irrelevant-formals
        • 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
        • Oracle-eval
        • Defmacro-untouchable
        • <<
        • Primitive
        • Revert-world
        • Unmemoize
        • Set-duplicate-keys-action
        • Symbols
        • Def-list-constructor
        • Easy-simplify-term
        • Defiteration
        • Fake-oracle-eval
        • Defopen
        • Sleep
      • Operational-semantics
      • Real
      • Start-here
      • Debugging
      • Miscellaneous
      • Output-controls
      • Macros
      • Interfacing-tools
    • Interfacing-tools
    • Hardware-verification
    • Software-verification
    • Math
    • Testing-utilities
  • Programming

State

The von Neumannesque ACL2 state object

Note: If you are interested in programming with state, see programming-with-state after reading the information below.

The ACL2 state object is used extensively in programming the ACL2 system, and has been used in other ACL2 programs as well. However, most users, especially those interested in specification and verification (as opposed to programming per se), need not be aware of the role of the state object in ACL2, and will not write functions that use it explicitly. We say more about this point at the end of this documentation topic.

The ACL2 state object is an example of a single-threaded object or stobj. ACL2 allows the user to define new single-threaded objects. Generally, ACL2 may need to access the ACL2 state but should not (cannot) change it except via a certain set of approved functions such as defun and defthm. If you need a state-like object to which you have complete rights, you may want a stobj.

Key to the idea of our state is the notion of single-threadedness. For an explanation, see stobj. The upshot of it is that state is a variable symbol with severe restrictions on its use, so that it can be passed into only certain functions in certain slots, and must be returned by those functions that ``modify'' it. Henceforth, we do not discuss single-threaded objects in general (which the user can introduce with defstobj and defabsstobj) but one in particular, namely ACL2's state object.

The global table is perhaps the most visible portion of the state object. Using the interface functions @ and assign, a user may bind global variables to the results of function evaluations (much as an Nqthm user exploits the Nqthm utility r-loop). See @, and see assign. A particularly interesting global is 'current-acl2-world, whose value is the ACL2 logical world.

ACL2 supports several facilities of a truly von Neumannesque state machine character, including file io and global variables. Logically speaking, the state is a true list of the 14 components described below. There is a ``current'' state object at the top-level of the ACL2 command loop. This object is understood to be the value of what would otherwise be the free variable state appearing in top-level input. When any command returns a state object as one of its values, that object becomes the new current state. But ACL2 provides von Neumann style speed for state operations by maintaining only one physical (as opposed to logical) state object. Operations on the state are in fact destructive. This implementation does not violate the applicative semantics because we enforce certain draconian syntactic rules regarding the use of state objects. For example, one cannot ``hold on'' to an old state, access the components of a state arbitrarily, or ``modify'' a state object without passing it on to subsequent state-sensitive functions.

Every routine that uses the state facilities (e.g. does io, or calls a routine that does io), must be passed a ``state object.'' And a routine must return a state object if the routine modifies the state in any way. Rigid syntactic rules governing the use of state objects are enforced by the function translate, through which all ACL2 user input first passes. State objects can only be ``held'' in the formal parameter state, never in any other formal parameter and never in any structure (except as a state value in a multiple-value return). State objects can only be accessed with the primitives we specifically permit. Thus, for example, one cannot ask, in code to be executed, for the length of state or the car of state. In the statement and proof of theorems, there are no syntactic rules prohibiting arbitrary treatment of state objects.

Logically speaking, a state object is a true list whose members are as follows:

Open-input-channels, an alist with keys that are symbols in package "ACL2-INPUT-CHANNEL". The value (cdr) of each pair has the form ((:header type file-name open-time) . elements), where type is one of :character, :byte, or :object and elements is a list of things of the corresponding type, i.e. characters, integers of type (mod 255), or lisp objects in our theory. File-name is a string. Open-time is an integer. See io.

Open-output-channels, an alist with keys that are symbols in package "ACL2-OUTPUT-CHANNEL". The value of a pair has the form ((:header type file-name open-time) . current-contents). See io.

Global-table, an alist associating symbols (to be used as ``global variables'') with values. See @, and see assign.

Idates, a list of dates and times, used to implement the function print-current-idate, which prints the date and time.

Acl2-oracle, a list of objects, used for example to implement the functions that let ACL2 report how much time was used, but inaccessible to the user. See read-ACL2-oracle and also see with-prover-time-limit.

File-clock, an integer that is increased on every file opening and closing, and is used to maintain the consistency of the io primitives.

Readable-files, an alist whose keys have the form (string type time), where string is a file name and time is an integer. The value associated with such a key is a list of characters, bytes, or objects, according to type. The time field is used in the following way: when it comes time to open a file for input, we will only look for a file of the specified name and type whose time field is that of file-clock. This permits us to have a ``probe-file'' aspect to open-file: one can ask for a file, find it does not exist, but come back later and find that it does now exist.

Written-files, an alist whose keys have the form (string type time1 time2), where string is a file name, type is one of :character, :byte or :object, and time1 and time2 are integers. Time1 and time2 correspond to the file-clock time at which the channel for the file was opened and closed. This field is write-only; the only operation that affects this field is close-output-channel, which conses a new entry on the front.

Read-files, a list of the form (string type time1 time2), where string is a file name and time1 and time2 were the times at which the file was opened for reading and closed. This field is write only.

Writeable-files, an alist whose keys have the form (string type time). To open a file for output, we require that the name, type, and time be on this list.

User-stobj-alist, an alist which associates user-defined single-threaded objects (see stobj) with their values.

We recommend avoiding the use of the state object when writing ACL2 code intended to be used as a formal model of some system, for several reasons. First, the state object is complicated and contains many components that are oriented toward implementation and are likely to be irrelevant to the model in question. Second, there is currently not much support for reasoning about ACL2 functions that manipulate the state object, beyond their logical definitions. Third, the documentation about state is not as complete as one might wish.

User-defined single-threaded objects offer the speed of state while giving the user complete access to all the fields. See stobj.

Again, if you are interested in programming with state see programming-with-state.

Subtopics

World
ACL2 property lists and the ACL2 logical database
Io
Input/output facilities in ACL2
Wormhole
ld without state — a short-cut to a parallel universe
Programming-with-state
Programming using the von Neumannesque ACL2 state object
W
The current ACL2 world
Set-state-ok
Allow the use of STATE as a formal parameter
Random$
Obtain a random value