• 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
        • Mutual-recursion
        • Memoize
        • Mbe
        • Io
        • Defpkg
        • Apply$
        • Loop$
          • Loop$-primer
            • Lp-section-8
            • Lp-section-10
              • Lp-section-6
              • Lp-section-9
              • Lp-section-17
              • Lp-section-16
              • Lp-section-15
              • Lp-section-11
              • Lp-section-4
              • Lp-section-7
              • Lp-section-13
              • Lp-section-12
              • Lp-section-14
              • Lp-section-5
              • Lp-section-0
              • Lp-section-2
              • Lp-section-18
              • Lp-section-3
              • Lp-section-1
            • Do-loop$
            • For-loop$
            • Loop$-recursion
            • Stating-and-proving-lemmas-about-loop$s
            • Loop$-recursion-induction
            • Do$
          • Programming-with-state
          • Arrays
          • Characters
          • Time$
          • Defmacro
          • Loop$-primer
            • Lp-section-8
            • Lp-section-10
              • Lp-section-6
              • Lp-section-9
              • Lp-section-17
              • Lp-section-16
              • Lp-section-15
              • Lp-section-11
              • Lp-section-4
              • Lp-section-7
              • Lp-section-13
              • Lp-section-12
              • Lp-section-14
              • Lp-section-5
              • Lp-section-0
              • Lp-section-2
              • Lp-section-18
              • Lp-section-3
              • Lp-section-1
            • Fast-alists
            • Defconst
            • Evaluation
            • Guard
            • Equality-variants
            • Compilation
            • Hons
            • ACL2-built-ins
              • Let
              • Declare
              • Mbe
              • Apply$
              • Fmt
              • Loop$
                • Loop$-primer
                  • Lp-section-8
                  • Lp-section-10
                    • Lp-section-6
                    • Lp-section-9
                    • Lp-section-17
                    • Lp-section-16
                    • Lp-section-15
                    • Lp-section-11
                    • Lp-section-4
                    • Lp-section-7
                    • Lp-section-13
                    • Lp-section-12
                    • Lp-section-14
                    • Lp-section-5
                    • Lp-section-0
                    • Lp-section-2
                    • Lp-section-18
                    • Lp-section-3
                    • Lp-section-1
                  • Do-loop$
                  • For-loop$
                  • Loop$-recursion
                  • Stating-and-proving-lemmas-about-loop$s
                  • Loop$-recursion-induction
                  • Do$
                • Return-last
                • Mv-let
                • Df
                • Pseudo-termp
                • Defwarrant
                • Time$
                • Mbt
                • Ec-call
                • Mv-nth
                • Sys-call
                • Msg
                • Er
                • Value-triple
                • O-p
                • Comp
                • Member
                • O<
                • Cw
                • Flet
                • Or
                • Hons
                • Cbd
                • Mv
                • Defbadge
                • Append
                • *ACL2-exports*
                • Comment
                • Eql
                • List
                • Unsigned-byte-p
                • Posp
                • Natp
                • The
                • Nth
                • And
                • Len
                • Time-tracker
                • Term-order
                • True-listp
                • Msgp
                • Booleanp
                • <
                • If
                • Pseudo-term-listp
                • +
                • Not
                • With-global-stobj
                • Bitp
                • Equal
                • Cdr
                • Car
                • String-listp
                • Nat-listp
                • Implies
                • Iff
                • Character-listp
                • Alistp
                • Cons
                • Symbol-listp
                • Macrolet
                • Quote
                • Integerp
                • Consp
                • True-list-listp
                • State-global-let*
                • Compress1
                • Symbolp
                • Stringp
                • *common-lisp-symbols-from-main-lisp-package*
                • Characterp
                • Prog2$
                • *
                • Last-prover-steps
                • Hons-acons
                • Let*
                • Eq
                • With-guard-checking
                • @
                • Length
                • With-local-stobj
                • Hard-error
                • -
                • Zp
                • Search
                • Intersection$
                • Assign
                • Aset1
                • Symbol-name
                • Union$
                • Set-gc-strategy
                • In-tau-intervalp
                • Cons-with-hint
                • Break-on-error
                • Pand
                • Case-match
                • Fast-alist-fork
                • Sys-call+
                • Signed-byte-p
                • ACL2-count
                • Remove-duplicates
                • With-serialize-character
                • Observation
                • Hons-resize
                • Make-tau-interval
                • Logbitp
                • Termp
                • Position
                • Assoc
                • *standard-co*
                • Hons-acons!
                • Update-nth
                • Take
                • Aref1
                • Read-run-time
                • Keywordp
                • Symbol-package-name
                • Symbol-alistp
                • Hons-wash
                • Expt
                • Coerce
                • Get-internal-time
                • Intern
                • Non-exec
                • Case
                • Standard-oi
                • Standard-co
                • Formula
                • Nthcdr
                • Atom
                • Without-evisc
                • Good-bye
                • With-local-state
                • Spec-mv-let
                • Intern-in-package-of-symbol
                • Binary-+
                • <=
                • Ash
                • With-fast-alist
                • Set-difference$
                • Hons-clear
                • Flush-compress
                • Rationalp
                • Por
                • Rassoc
                • Remove-assoc
                • =
                • Pargs
                • Nfix
                • Hons-copy
                • Alphorder
                • Subsetp
                • Logand
                • Remove1-assoc
                • No-duplicatesp
                • Mv-list
                • Canonical-pathname
                • Aset2
                • Floor
                • Serialize-read
                • Random$
                • Fmt-to-comment-window
                • F-put-global
                • Compress2
                • Concatenate
                • Fast-alist-clean
                • Assert$
                • Remove
                • Remove1
                • Intersectp
                • Endp
                • Put-assoc
                • Princ$
                • Primitive
                • Keyword-value-listp
                • True-list-fix
                • Swap-stobjs
                • Integer-listp
                • Illegal
                • Hons-get
                • With-output-lock
                • Setenv$
                • Open-output-channel!
                • Fast-alist-free
                • Er-progn
                • Cw-print-base-radix
                • Reverse
                • Cond
                • Complex
                • Add-to-set
                • Truncate
                • Digit-char-p
                • Code-char
                • Char-code
                • Set-print-case
                • Set-print-base
                • Read-ACL2-oracle
                • Error1
                • Print-object$
                • Plet
                • Integer-length
                • Zip
                • With-live-state
                • Hons-assoc-equal
                • Extend-pathname
                • Logior
                • In-package
                • With-guard-checking-event
                • Term-listp
                • Print-object$+
                • Fmx-cw
                • String
                • Mod
                • Unary--
                • Set-print-radix
                • Resize-list
                • Pkg-witness
                • Revappend
                • Null
                • Term-list-listp
                • Make-fast-alist
                • Header
                • Boole$
                • Subseq
                • With-guard-checking-error-triple
                • /
                • Make-list
                • Logxor
                • Char-upcase
                • Char-downcase
                • Strip-cars
                • Set-fmt-hard-right-margin
                • Make-ord
                • Ifix
                • Fast-alist-free-on-exit
                • F-get-global
                • Aref2
                • Standard-char-p
                • Lognot
                • Last
                • Must-be-equal
                • Integer-range-p
                • Getenv$
                • Binary-append
                • Er-hard
                • Eqlablep
                • Cpu-core-count
                • Boolean-listp
                • Allocate-fixnum-range
                • ACL2-numberp
                • Butlast
                • Pairlis$
                • Mod-expt
                • Hons-equal
                • Gc$
                • Substitute
                • Ceiling
                • With-stolen-alist
                • Mv?-let
                • String-upcase
                • String-downcase
                • Round
                • Count
                • Char
                • Sys-call-status
                • Progn$
                • Pprogn
                • Lexorder
                • Hons-summary
                • Break$
                • Assert*
                • Alpha-char-p
                • Strip-cdrs
                • Serialize-write
                • Keyword-listp
                • Upper-case-p
                • Lower-case-p
                • Logeqv
                • List*
                • Proofs-co
                • Maximum-length
                • Fix
                • Explode-nonnegative-integer
                • Eqlable-listp
                • Dimensions
                • Default
                • Arity
                • Sublis
                • Max
                • Evenp
                • Explode-atom
                • Change
                • Zerop
                • String<
                • String-equal
                • Abs
                • Set-print-base-radix
                • Print-base-p
                • Nonnegative-integer-quotient
                • Intern$
                • Getprop
                • Binary-*
                • Aset1-trusted
                • Symbol<
                • String-append
                • Rfix
                • Mv?
                • Logic-fns-list-listp
                • Fast-alist-fork!
                • Er-hard?
                • Char-equal
                • 1+
                • *standard-oi*
                • Sys-call*
                • Pos-listp
                • Mbt*
                • Hons-wash!
                • Hons-clear!
                • Signum
                • Rem
                • Real/rationalp
                • Rational-listp
                • O-first-coeff
                • Logic-fnsp
                • Logic-fns-listp
                • Hons-copy-persistent
                • Gc-strategy
                • Fast-alist-summary
                • String>=
                • String<=
                • Acons
                • O-first-expt
                • Fast-alist-clean!
                • >=
                • >
                • Subst
                • Logcount
                • Getpropc
                • Evens
                • Er-soft
                • Digit-to-char
                • Comp-gcl
                • Atom-listp
                • Arities-okp
                • ACL2-number-listp
                • /=
                • Cadr
                • *standard-ci*
                • Unary-/
                • The-true-list
                • Realfix
                • O-rst
                • Fast-alist-len
                • Complex/complex-rationalp
                • Array2p
                • Array1p
                • Logtest
                • Logandc1
                • Char<
                • Trace-co
                • Putprop
                • Get-real-time
                • Eqlable-alistp
                • Count-keys
                • Assoc-string-equal
                • Logorc1
                • Logandc2
                • Denominator
                • 1-
                • Packn
                • Logic-termp
                • Logic-term-list-listp
                • Fmt!
                • Fms
                • Cw!
                • Assoc-keyword
                • String>
                • Numerator
                • Logorc2
                • Char>=
                • Update-nth-array
                • The-number
                • Odds
                • Makunbound-global
                • Make-character-list
                • Make
                • List$
                • Int=
                • Get-cpu-time
                • Fmt-to-comment-window!
                • Fms!
                • F-boundp-global
                • Complex-rationalp
                • Alist-to-doublets
                • Access
                • Min
                • Lognor
                • Listp
                • Identity
                • Char>
                • Char<=
                • Zpf
                • Standard-char-listp
                • O-finp
                • Number-subtrees
                • Logic-term-listp
                • Last-cdr
                • Fmt1!
                • Fmt-to-comment-window!+
                • Character-alistp
                • Oddp
                • Minusp
                • Lognand
                • Imagpart
                • Conjugate
                • Xor
                • Unquote
                • String-alistp
                • Packn-pos
                • Maybe-flush-and-compress1
                • Kwote
                • Fmt1
                • Fmt-to-comment-window+
                • Cw-print-base-radix!
                • Alist-keys-subsetp
                • Realpart
                • Plusp
                • First
                • Symbol-name-lst
                • R-symbol-alistp
                • R-eqlable-alistp
                • Fmx
                • Cw!+
                • Cons-subtrees
                • Cons-count-bounded
                • Cddr
                • Caar
                • Proper-consp
                • Kwote-lst
                • Improper-consp
                • Cw+
                • Rest
                • Standard-char-p+
                • Mbe1
                • Caddr
                • Pairlis-x2
                • Pairlis-x1
                • O>=
                • O<=
                • O-infp
                • Merge-sort-lexorder
                • Fix-true-list
                • Cdddr
                • Set-fmt-soft-right-margin
                • Real-listp
                • O>
                • Cddar
                • Cdar
                • Cdadr
                • Cdaar
                • Cadar
                • Caadr
                • Caaar
                • Cadddr
                • Caddar
                • Third
                • Tenth
                • Sixth
                • Seventh
                • Second
                • Ninth
                • Fourth
                • Fifth
                • Eighth
                • Cddddr
                • Cdddar
                • Cddadr
                • Cddaar
                • Cdaddr
                • Cdadar
                • Cdaadr
                • Cdaaar
                • Cadadr
                • Cadaar
                • Caaddr
                • Caadar
                • Caaadr
                • Caaaar
                • Hons-shrink-alist!
                • Hons-shrink-alist
                • Flush-hons-get-hash-table-link
                • Delete-assoc
              • 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
        • Loop$-primer

        Lp-section-10

        The Evaluation of the Formal Semantics of a Fancy Loop$

        LP10: The Evaluation of the Formal Semantics of a Fancy Loop$

        Below we show the evaluation of a fancy loop$ that uses the function packn to create a list of symbols. We start with an example of packn so you can infer its behavior. But our real interest is the behavior of the loop$.

        ACL2 !>(packn (list 'R2 '- 'D 2))
        R2-D2
        ACL2 !>(let ((mark '*))
                 (loop$ for x in '(a * b c d e * f g h i j * k)
                        as  y in '(u v * w * u v * x y z)
                        as  i from 0 to 100 by 3
                        when (and (evenp i)
                                  (not (eq x mark))
                                  (not (eq y mark)))
                        collect (packn (list x y '_ i))))
        (AU_0 GX_24 IZ_30)
        ACL2 !>

        We now explain carefully the evaluation of the loop$ expression above in an environment in which mark is bound to the asterisk symbol, *.

        The first three lines of the loop$ introduce the so-called iteration variables, x, y, and i, and their respective ranges.

        The when clause specifies a predicate on the iteration variables, identifying the “good” cases, i.e., the values of the iteration variables that we care about. However, note that the predicate above mentions the variable mark, which is not one of the iteration variables. We call such variables globals because their values are not set within the scope of the loop.

        The collect clause specifies an expression to be evaluated on the “good” iteration variable values and collects the results of those evaluations.

        If you replace the symbol loop$ above by loop you get a legal Common Lisp loop expression with the same value (if executed when mark is bound to *).

        For our purposes, the easiest way to think about this particular statement is to decompose it into three steps.

        Step 1: The lines introducing the iteration variables and their ranges cause us to make a table of corresponding values of x, y, and i, as shown below in the form of a list of triples. This list is as long as the shortest individual range.

        ; x y  i
        ((A U  0)
         (* V  3)
         (B *  6)
         (C W  9)
         (D * 12)
         (E U 15)
         (* V 18)
         (F * 21)
         (G X 24)
         (H Y 27)
         (I Z 30)).

        Step 2: the when clause maps over the above table and identifies the entries as “good” or “bad”, where the good ones have an even value for i and values for x and y that are not the asterisk mark, *. We annotate the table accordingly below.

        ; x y  i
        ((A U  0)        ; GOOD!
         (* V  3)        ; bad: odd i (and asterisk)
         (B *  6)        ; bad: asterisk
         (C W  9)        ; bad: odd i
         (D * 12)        ; bad: asterisk
         (E U 15)        ; bad: odd i
         (* V 18)        ; bad: asterisk
         (F * 21)        ; bad: odd i (and asterisk)
         (G X 24)        ; GOOD!
         (H Y 27)        ; bad: odd i
         (I Z 30)).      ; GOOD!

        Effectively the when clause pares down the table to just the good entries.

        ; x y  i
        ((A U  0)        ; GOOD!
         (G X 24)        ; GOOD!
         (I Z 30)).      ; GOOD!

        Step 3: the collect clause maps over pared-down table, evaluating and collecting the results of (packn (list x y '_ i)) for each triple in the table.

        (AU_0
         GX_24
         IZ_30).

        The ACL2 semantics of the loop$ statement reflects this understanding of the statement. (The display below is the output of :tca on the loop$, but with the DECLARE forms deleted and the three comments added.)

          (collect$+                                        ; step 3
           (lambda$ (loop$-gvars loop$-ivars)
                    (let ((x (car loop$-ivars))
                          (y (cadr loop$-ivars))
                          (i (caddr loop$-ivars)))
                      (packn (list x y '_ i))))
           nil
           (when$+                                          ; step 2
            (lambda$ (loop$-gvars loop$-ivars)
                     (let ((mark (car loop$-gvars))
                           (x (car loop$-ivars))
                           (y (cadr loop$-ivars))
                           (i (caddr loop$-ivars)))
                       (and (evenp i)
                            (not (eq x mark))
        		    (not (eq y mark)))))
            (list mark)
            (loop$-as (list '(a * b c d e * f g h i j * k)  ; step 1
                            '(u v * w * u v * x y z)
                            (from-to-by 0 100 3)))))

        In step 1, the loop$-as function takes a list of the individual ranges and builds the first version of the iteration variable table. The function from-to-by just enumerates the integers from its first argument to its second argument in steps of size given by its third argument.

        In step 2, the when$+ function takes three arguments. Note that the last argument of the when$+ function is the iteration variable table computed by step 1. The first argument of the when$+ function is a lambda$ expression representing the predicate used to identify the “good” entries. But that predicate may also require the value of any global variables used. So the lambda$ expression has two arguments, loop$-gvars, the list of values of the global variables, and loop$-ivars, a tuple of values corresponding to a line in the iteration variable table. The middle argument of the when$+ provides the values of the global variables and, as noted earlier, the last argument is the iteration variable table. The when$+ maps over the iteration variable table and collects the “good” lines, returning them as a list.

        In step 3, the collect$+ takes three arguments. The first is a lambda$ expression on the loop$-gvars and loop$-ivars as above. The second and third arguments are the global variable values and the “good” lines from the pared-down iteration variable table as computed by step 2. Note that since the collect clause does not mention any global variables the global variable tuple in the second argument of the collect$+ is nil.

        Of course, Common Lisp does not decompose the corresponding loop statement this way but generates much more efficient compiled code.

        The ACL2 semantics is rendered compositionally to make it easier to reason about loop$ statements. If the guards of the loop$ statement — which we haven't discussed yet — are verified then the ACL2 loop$ statement is rendered into the corresponding Common Lisp loop statement, compiled, and efficiently executed.

        Now go to lp-section-11 (or return to the Table of Contents).