Documentation

Bignum.Arm.Spec

Specification Framework for ARM Verification #

This file defines the specification framework for verifying ARM programs, following the relational Hoare logic approach from s2n-bignum.

The framework is organized following the article "Relational Hoare Logic for Realistically Modelled Machine Code" (CAV 2025):

Unary Hoare Logic L₁ #

Relational Logic L₂ (for future extension) #

Frame Conditions #

References #

Source: s2n-bignum/common/relational.ml (HOL Light implementation)

Operational Semantics - Eventually #

eventually step P s holds if predicate P is reachable from state s through the transition relation step.

The two inference rules:

  1. base: If P s already holds, then eventually step P s
  2. step: If there exists a next state AND all next states satisfy eventually step P, then eventually step P s
inductive Bignum.Arm.eventually {α : Sort u_1} (step : ααProp) (P : αProp) :
αProp

Reachability predicate: eventually step P s holds if P is reachable from s via the transition relation step.

  • base {α : Sort u_1} {step : ααProp} {P : αProp} {s : α} : P seventually step P s
  • ind {α : Sort u_1} {step : ααProp} {P : αProp} {s : α} (h₁ : ∃ (s' : α), step s s') (h₂ : ∀ (s' : α), step s s'eventually step P s') : eventually step P s
Instances For

    Hoare Triple - Ensures #

    The ensures predicate defines Hoare triples with frame conditions:

    "If precondition P holds in state s, then following the operational semantics (step), we eventually reach a state s' where:

    • The postcondition Q s' holds
    • The frame C s s' holds (only allowed components changed)"

    This corresponds to the axiomatic semantics (Hoare logic) built ON TOP of the operational semantics (eventually).

    def Bignum.Arm.ensures {α : Sort u_1} (step : ααProp) (pre post : αProp) (frame : ααProp) :

    ensures step pre post frame is the formal specification that from any state satisfying pre, we eventually reach a state satisfying post ∧ frame.

    Equations
    Instances For

      Theorems for Eventually and Ensures #

      theorem Bignum.Arm.eventually_mono {α : Sort u_1} {step : ααProp} {P Q : αProp} (h : ∀ (s : α), P sQ s) (s : α) :
      eventually step P seventually step Q s

      Monotonicity of eventually: if P implies Q, then eventually P implies eventually Q.

      Relational Composition #

      We use Mathlib's Relation.Comp for frame composition, which corresponds to HOL Light's ,, operator from s2n-bignum/common/relational.ml:26-27:

      Notation for relational composition matching HOL Light's ,, operator.

      Equations
      Instances For
        theorem Bignum.Arm.eventually_trans {α : Sort u_1} {step : ααProp} {P Q : αProp} (h : ∀ (s : α), P seventually step Q s) (s : α) :
        eventually step P seventually step Q s
        theorem Bignum.Arm.ensures_trans {α : Sort u_1} {step : ααProp} {P Q R : αProp} {C1 C2 : ααProp} (h1 : ensures step P Q C1) (h2 : ensures step Q R C2) :
        ensures step P R (C1 ,, C2)

        Transitivity of ensures: composing two ensures specifications.

        Source: s2n-bignum/common/relational.ml:1373-1393 (ENSURES_TRANS)

        theorem Bignum.Arm.ensures_trans_simple {α : Sort u_1} {step : ααProp} {P Q R : αProp} {C : ααProp} (h_idem : ∀ (s₀ s₂ : α), (C ,, C) s₀ s₂C s₀ s₂) (h1 : ensures step P Q C) (h2 : ensures step Q R C) :
        ensures step P R C

        Simplified transitivity when frames are idempotent under relational composition (C ,, C = C).

        This holds for MAYCHANGE-style frames where C s s' means "only certain components may differ between s and s'". Such frames are idempotent because if only certain components may change from s to s₁, and only those same components may change from s₁ to s', then only those components may change from s to s'.

        Source: s2n-bignum/common/relational.ml:1394-1399 (ENSURES_TRANS_SIMPLE)

        ARM Step Relation #

        The arm step relation defines single-instruction execution using fetch-decode- execute from memory, matching HOL Light's architecture where programs live in memory rather than as a separate structure.

        ARM single-step relation: arm s s' holds if s' is the result of executing one instruction from state s.

        This corresponds to HOL Light's arm step relation. The execution:

        1. Reads the PC
        2. Fetches and decodes the instruction at PC from memory
        3. Executes the instruction
        4. Advances the PC (handled by step)

        This definition keeps programs in memory, matching the paper's model where the machine state includes both data and code memory.

        Equations
        Instances For

          A program (as machine code bytes) is loaded at the given base address.

          This corresponds to HOL Light's aligned_bytes_loaded combined with a PC check. Used in preconditions to assert that the program bytes are in memory.

          Equations
          Instances For

            Alternative: program bytes loaded without PC constraint.

            Equations
            Instances For
              @[reducible, inline]
              abbrev Bignum.Arm.ensures_arm (pre post : ArmStateProp) (frame : ArmStateArmStateProp) :

              Convenience: ensures_arm specialized to the ARM step relation.

              This is the primary interface for ARM program verification:

              ensures_arm
                (fun s => program_loaded s base mc ∧ ...)  -- precondition
                (fun s => s.read_reg Reg.PC = ... ∧ ...)   -- postcondition
                (maychange_regs [Reg.PC, ...])             -- frame
              
              Equations
              Instances For

                Frame Conditions (MAYCHANGE) #

                Frame conditions specify which components of the state MAY change during program execution. Everything not in the frame must remain unchanged.

                source: s2n-bignum/common/relational.ml

                In HOL Light, ASSIGNS and MAYCHANGE have the following semantics:

                (* ASSIGNS c s s' means: there exists some value y such that s' = write c y s *)
                (* i.e., s' differs from s only in component c *)
                ASSIGNS (c:(A,B)component) s s' <=> exists y. (c := y) s s'
                
                (* MAYCHANGE is relational composition of ASSIGNS *)
                MAYCHANGE [] = (=)   (* equality relation: nothing changes *)
                MAYCHANGE (CONS c cs) = ASSIGNS c ,, MAYCHANGE cs
                

                For example: MAYCHANGE [PC; X2] = ASSIGNS PC ,, ASSIGNS X2

                The key insight is that ASSIGNS c is trivially satisfiable for any two states (we can always choose y = read c s'). The real constraint comes from the composition: if only components in the list may change, then all other components must remain equal.

                We use a simplified but equivalent formulation:

                Constructive vs Observational equivalence: HOL Light's ASSIGNS c s s' is constructive: it asserts s' = write c y s for some y. Our formulation is observational: it only asserts equality of values. These are equivalent when write is "pure" (only affects the target component) and the state has no hidden fields.

                def Bignum.Arm.unchanged_reg (r : Reg) (s₁ s₂ : ArmState) :

                A register must not change between two states.

                Equations
                Instances For
                  def Bignum.Arm.unchanged_mem (addr : Address) (s₁ s₂ : ArmState) :

                  Memory at an address must not change.

                  Equations
                  Instances For

                    All flags must not change between two states.

                    Equations
                    Instances For
                      def Bignum.Arm.unchanged_flag (f : Flag) (s₁ s₂ : ArmState) :

                      An individual flag must not change between two states.

                      Equations
                      Instances For
                        def Bignum.Arm.maychange_regs (regs : List Reg) (s₁ s₂ : ArmState) :

                        maychange_regs regs s₁ s₂ holds when all registers NOT in regs are unchanged. This is equivalent to HOL Light's MAYCHANGE [r1; r2; ...] for registers: the registers in the list MAY change (no constraint), while all others must remain equal.

                        Source: s2n-bignum/common/relational.ml

                        Equations
                        Instances For
                          def Bignum.Arm.maychange_mem (addrs : List Address) (s₁ s₂ : ArmState) :

                          maychange_mem addrs s₁ s₂ holds when all memory addresses NOT in addrs are unchanged.

                          Equations
                          Instances For
                            def Bignum.Arm.maychange_flags (flags : List Flag) (s₁ s₂ : ArmState) :

                            maychange_flags flags s₁ s₂ holds when all flags NOT in flags are unchanged.

                            This allows fine-grained control like MAYCHANGE [CF; ZF] in HOL Light.

                            Source: s2n-bignum/arm/proofs/instruction.ml:186-192

                            Equations
                            Instances For

                              Combine frame conditions via conjunction.

                              When we have maychange_regs regs ∧ maychange_mem addrs, both constraints must hold: registers outside regs are unchanged AND memory outside addrs is unchanged.

                              Equations
                              • (f1 f2) s₁ s₂ = (f1 s₁ s₂ f2 s₁ s₂)
                              Instances For

                                Idempotence of Frame Conditions #

                                A key property for ensures_trans_simple is that MAYCHANGE-style frames are idempotent under relational composition: C ,, C = C.

                                This holds because:

                                theorem Bignum.Arm.maychange_regs_idem (regs : List Reg) (s₀ s₂ : ArmState) :
                                (maychange_regs regs ,, maychange_regs regs) s₀ s₂maychange_regs regs s₀ s₂

                                maychange_regs is idempotent under relational composition.

                                Source: s2n-bignum/common/relational.ml:188-192 (ASSIGNS_ABSORB_SAME_COMPONENTS)

                                Reflexivity: maychange_regs regs s s always holds (nothing changed).

                                This corresponds to HOL Light's (=) subsumed MAYCHANGE [...].