• Top
    • Documentation
    • Books
    • Recursion-and-induction
    • Boolean-reasoning
    • Projects
    • Debugging
    • Std
    • Proof-automation
      • Gl
        • Term-level-reasoning
        • Glmc
        • Other-resources
        • Optimization
        • Reference
        • Debugging
        • Basic-tutorial
          • 7. Proving Coverage
          • 4. Proving Theorems by Symbolic Execution
          • 2. Symbolic Objects
          • 5. Using def-gl-thm
          • 6. Writing :g-bindings forms
            • 3. Computing with Symbolic Objects
            • 1. An Example GL Proof
            • 8. Exercises
        • Witness-cp
        • Ccg
        • Install-not-normalized
        • Rewrite$
        • Removable-runes
        • Efficiency
        • Rewrite-bounds
        • Bash
        • Def-dag-measure
        • Fgl
        • Bdd
        • Remove-hyps
        • Contextual-rewriting
        • Simp
        • Rewrite$-hyps
        • Bash-term-to-dnf
        • Use-trivial-ancestors-check
        • Minimal-runes
        • Clause-processor-tools
        • Fn-is-body
        • Without-subsumption
        • Rewrite-equiv-hint
        • Def-bounds
        • Rewrite$-context
        • Try-gl-concls
        • Hint-utils
      • Macro-libraries
      • ACL2
      • Interfacing-tools
      • Hardware-verification
      • Software-verification
      • Testing-utilities
      • Math
    • Basic-tutorial

    6. Writing :g-bindings forms

    In a typical def-gl-thm command, the :g-bindings should have an entry for every free variable in the theorem. Here is an example that shows some typical bindings.

    :g-bindings '((flag   (:g-boolean . 0))
                  (a-bus  (:g-integer 1 3 5 7 9))
                  (b-bus  (:g-integer 2 4 6 8 10))
                  (mode   (:g-ite (:g-boolean . 11) exact . fast))
                  (opcode #b0010100))

    These bindings allow flag to take an arbitrary Boolean value, a-bus and b-bus any five-bit signed integer values, mode either the symbol exact or fast, and opcode only the value 20.

    (Aside: Note that since #b0010100 is not within a :g-boolean or :g-integer form, it is not the index of a Boolean variable. Instead, like the symbols exact and fast, it is just an ordinary ACL2 constant that stands for itself, i.e., 20.)

    These :g-boolean and :g-integer are called shape-specs. They are similar to the symbolic objects GL uses to compute with, except that natural number indices take the places of Boolean expressions. The indices used throughout all of the bindings must be distinct, and represent free, independent Boolean variables.

    In BDD mode, these indices have additional meaning: they specify the BDD variable ordering, with smaller indices coming first in the order. This ordering can greatly affect performance. In AIG mode the choice of indices has no particular bearing on efficiency.

    How do you choose a good BDD ordering? It is often good to interleave the bits of data buses that are going to be combined in some way. It is also typically a good idea to put any important control signals such as opcodes and mode settings before the data buses.

    Often the same :g-bindings can be used throughout several theorems, either verbatim or with only small changes. In practice, we almost always generate the :g-bindings forms by calling functions or macros. One convenient function is

    (g-int start by n)

    which generates a :g-integer form with n bits, using indices that start at start and increment by by. This is particularly useful for interleaving the bits of numbers, as we did for the a-bus and b-bus bindings above:

    (g-int 1 2 5)  ---> (:g-integer 1 3 5 7 9)
    (g-int 2 2 5)  ---> (:g-integer 2 4 6 8 10)

    Writing out :g-bindings and getting all the indices can be tedious. See auto-bindings for a convenient macro that helps ensure that all the indices are different.