3. The Assembly Line
The step function of the last chapter executes one instruction per move, in one tidy motion: fetch, do the work, advance. Real hardware built that way would be slow, because each part of the chip would sit idle while the others took their turn. Every fast processor instead works like an assembly line — a pipeline: while one instruction executes, the next is already being decoded, and the one after that is being fetched. Three instructions are in flight at once, and the chip finishes one per cycle instead of one per three.
The danger is exactly what you would expect of an assembly line that starts building things before the previous item is finished. When a branch executes and decides to jump somewhere new, the two instructions behind it on the line — fetched on the assumption that no jump would happen — are the wrong instructions, and must be thrown away before they do any damage. Getting that squashing logic right, in every combination of circumstances, is historically where pipelined processors have gone wrong. It is also, therefore, exactly what this chapter proves correct.
3.1. What we will prove, and how
The claim has a standard shape, called a stuttering refinement. Think of the specification's execution as a film of the architectural state, one frame per instruction. The pipeline produces its own film, one frame per clock cycle — a longer film, because some cycles are spent filling the line or waiting, with nothing visible happening to the architectural state. The theorem says: if you delete the duplicate frames from the pipeline's film, you get exactly the specification's film. Same states, same messages to the neighbours, same halts. The pipeline is allowed to take its time; it is not allowed to invent, lose, or reorder anything observable.
One structural decision makes the proof honest and small at the same time.
Our pipeline model's execute stage is the step function — the previous
chapter's semantics, called as a subroutine on the architectural state.
This is not circular; it is the same factoring the hardware itself uses.
M0 decided each element has one shared execution unit, and whether that
unit's adder adds correctly is a separate, later proof at the gate level.
What the pipeline adds to the world is control: registers that hold
in-flight instructions, the shift-forward each cycle, and the squash on
redirect. Those are what this chapter's theorem is about, because those are
what overlap puts at risk.
3.2. The pipeline state
Three stages: fetch (F), decode (D), and issue/execute (I). The model keeps the committed architectural state, plus what each stage holds — for D and I, an instruction tagged with the address it came from; for F, just the address to fetch next. An empty slot is a bubble.
namespace Tilessa
/-- The pipeline's state: the committed architectural state plus the three
front-end stages. `irD`/`irI` hold an in-flight instruction tagged with its
address; `none` is a bubble. -/
structure PipeState (cfg : CoreConfig) where
arch : State cfg
pcF : BitVec 12
irD : Option (BitVec 12 × Instr)
irI : Option (BitVec 12 × Instr)
/-- Power-on: everything empty, fetch from address zero. -/
def PipeState.init (cfg : CoreConfig) : PipeState cfg where
arch := State.init cfg
pcF := 0
irD := none
irI := none
3.3. One clock cycle
Each cycle, the pipeline does one of the following. If the issue slot holds
an instruction, it executes it — by calling step — and then either shifts
the line forward (normal case), squashes the younger stages (a redirect:
the executed instruction changed the program counter, so everything fetched
behind it is wrong), holds everything in place (the instruction is waiting
on a mailbox), or stops for good (HALT). If the issue slot is a bubble, the
cycle just moves the line forward: whatever is in decode advances to issue,
and fetch refills decode.
/-- The outcome of one pipeline clock cycle. -/
inductive PipeResult (cfg : CoreConfig) where
| next (ps : PipeState cfg) (out : MeshOut cfg.wordBits)
| halt
/-- One clock cycle of the pipelined element. -/
def pstep (cfg : CoreConfig) (p : Program) (env : MeshIn cfg.wordBits)
(ps : PipeState cfg) : PipeResult cfg :=
match ps.irI with
| some _ =>
-- Issue slot occupied: execute via the semantics itself.
match step cfg p env ps.arch with
| .halt => .halt
| .stall => .next ps {}
| .next arch' out =>
if arch'.pc = ps.arch.pc + 1 then
-- Sequential commit: shift the line forward.
let ps' : PipeState cfg :=
{ arch := arch',
pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF),
irI := ps.irD }
.next ps' out
else
-- Redirect: the committed instruction jumped. Squash D and F.
let ps' : PipeState cfg :=
{ arch := arch',
pcF := arch'.pc,
irD := none,
irI := none }
.next ps' out
| none =>
-- Bubble in issue: advance the front end (a stutter).
match ps.irD with
| some (pcD, _) =>
let ps' : PipeState cfg :=
{ arch := { ps.arch with pc := pcD },
pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF),
irI := ps.irD }
.next ps' {}
| none =>
let ps' : PipeState cfg :=
{ arch := ps.arch,
pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF),
irI := none }
.next ps' {}
Notice the execute case consults ps.arch directly: by the time an
instruction sits in the issue slot, the invariant below guarantees the
architectural program counter points at it, so step fetches and executes
exactly the in-flight instruction.
3.4. The pipeline's promise
An assembly line is only correct if what is on the line corresponds to what should be built next. We state that as an invariant — four facts the pipeline maintains between every pair of cycles:
/-- The pipeline invariant: everything in flight is the right instruction
from the right address, and the addresses are consecutive. -/
structure PipeInv (cfg : CoreConfig) (p : Program) (ps : PipeState cfg) : Prop where
/-- The issue slot holds the instruction at the committed pc. -/
iOk : ∀ a i, ps.irI = some (a, i) → i = p a ∧ ps.arch.pc = a
/-- The decode slot holds the instruction its tag claims. -/
dOk : ∀ a j, ps.irD = some (a, j) → j = p a ∧ ps.pcF = a + 1
/-- Decode follows issue consecutively. -/
iSeqD : ∀ a i b j, ps.irI = some (a, i) → ps.irD = some (b, j) → b = a + 1
/-- With decode empty, fetch follows issue consecutively. -/
iSeqF : ∀ a i, ps.irI = some (a, i) → ps.irD = none → ps.pcF = a + 1
/-- The invariant holds at power-on. -/
theorem PipeInv.init (cfg : CoreConfig) (p : Program) :
PipeInv cfg p (PipeState.init cfg) where
iOk := cfg:CoreConfigp:Program⊢ ∀ (a : BitVec 12) (i : Instr), (PipeState.init cfg).irI = some (a, i) → i = p a ∧ (PipeState.init cfg).arch.pc = a cfg:CoreConfigp:Programa:BitVec 12i:Instrh:(PipeState.init cfg).irI = some (a, i)⊢ i = p a ∧ (PipeState.init cfg).arch.pc = a; All goals completed! 🐙
dOk := cfg:CoreConfigp:Program⊢ ∀ (a : BitVec 12) (j : Instr), (PipeState.init cfg).irD = some (a, j) → j = p a ∧ (PipeState.init cfg).pcF = a + 1 cfg:CoreConfigp:Programa:BitVec 12j:Instrh:(PipeState.init cfg).irD = some (a, j)⊢ j = p a ∧ (PipeState.init cfg).pcF = a + 1; All goals completed! 🐙
iSeqD := cfg:CoreConfigp:Program⊢ ∀ (a : BitVec 12) (i : Instr) (b : BitVec 12) (j : Instr),
(PipeState.init cfg).irI = some (a, i) → (PipeState.init cfg).irD = some (b, j) → b = a + 1 cfg:CoreConfigp:Programa:BitVec 12i:Instrb:BitVec 12j:Instrh:(PipeState.init cfg).irI = some (a, i)⊢ (PipeState.init cfg).irD = some (b, j) → b = a + 1; All goals completed! 🐙
iSeqF := cfg:CoreConfigp:Program⊢ ∀ (a : BitVec 12) (i : Instr),
(PipeState.init cfg).irI = some (a, i) → (PipeState.init cfg).irD = none → (PipeState.init cfg).pcF = a + 1 cfg:CoreConfigp:Programa:BitVec 12i:Instrh:(PipeState.init cfg).irI = some (a, i)⊢ (PipeState.init cfg).irD = none → (PipeState.init cfg).pcF = a + 1; All goals completed! 🐙
3.5. Seeing through the pipeline
To compare the two films frame by frame we need to say which architectural state a pipeline state depicts. The registers are simply the committed ones; the program counter is the address of the oldest instruction still in flight (or, if the line is empty, the next fetch address). This is the "delete the duplicate frames" lens:
/-- The architectural state a pipeline state depicts: committed state, with
the pc of the oldest in-flight instruction. -/
def absState (cfg : CoreConfig) (ps : PipeState cfg) : State cfg :=
match ps.irI, ps.irD with
| some _, _ => ps.arch
| none, some (b, _) => { ps.arch with pc := b }
| none, none => { ps.arch with pc := ps.pcF }
3.6. The theorem
Every pipeline cycle is one of two things, seen through the lens: a
stutter (the depicted state does not change, and nothing is said to the
neighbours) or a perfect step (the depicted state changes exactly as
step dictates, with exactly the same mailbox traffic). And a pipeline
halt happens only when the specification halts. The invariant survives
either way.
theorem pstep_refines (cfg : CoreConfig) (p : Program)
(env : MeshIn cfg.wordBits) (ps : PipeState cfg)
(hInv : PipeInv cfg p ps) :
(pstep cfg p env ps = .halt → step cfg p env (absState cfg ps) = .halt)
∧ (∀ ps' out, pstep cfg p env ps = .next ps' out →
PipeInv cfg p ps'
∧ ((absState cfg ps' = absState cfg ps ∧ out = {})
∨ step cfg p env (absState cfg ps) = .next (absState cfg ps') out)) := cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p ps⊢ (pstep cfg p env ps = PipeResult.halt → step cfg p env (absState cfg ps) = StepResult.halt) ∧
∀ (ps' : PipeState cfg) (out : MeshOut cfg.wordBits),
pstep cfg p env ps = PipeResult.next ps' out →
PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
cases hI : ps.irI with
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psv:BitVec 12 × InstrhI:ps.irI = some v⊢ (pstep cfg p env ps = PipeResult.halt → step cfg p env (absState cfg ps) = StepResult.halt) ∧
∀ (ps' : PipeState cfg) (out : MeshOut cfg.wordBits),
pstep cfg p env ps = PipeResult.next ps' out →
PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)⊢ (pstep cfg p env ps = PipeResult.halt → step cfg p env (absState cfg ps) = StepResult.halt) ∧
∀ (ps' : PipeState cfg) (out : MeshOut cfg.wordBits),
pstep cfg p env ps = PipeResult.next ps' out →
PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.arch⊢ (pstep cfg p env ps = PipeResult.halt → step cfg p env (absState cfg ps) = StepResult.halt) ∧
∀ (ps' : PipeState cfg) (out : MeshOut cfg.wordBits),
pstep cfg p env ps = PipeResult.next ps' out →
PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = a⊢ (pstep cfg p env ps = PipeResult.halt → step cfg p env (absState cfg ps) = StepResult.halt) ∧
∀ (ps' : PipeState cfg) (out : MeshOut cfg.wordBits),
pstep cfg p env ps = PipeResult.next ps' out →
PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
cases hs : step cfg p env ps.arch with
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = ahs:step cfg p env ps.arch = StepResult.halt⊢ (pstep cfg p env ps = PipeResult.halt → step cfg p env (absState cfg ps) = StepResult.halt) ∧
∀ (ps' : PipeState cfg) (out : MeshOut cfg.wordBits),
pstep cfg p env ps = PipeResult.next ps' out →
PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = ahs:step cfg p env ps.arch = StepResult.haltps':PipeState cfgout:MeshOut cfg.wordBitsh:pstep cfg p env ps = PipeResult.next ps' out⊢ PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
All goals completed! 🐙
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = ahs:step cfg p env ps.arch = StepResult.stall⊢ (pstep cfg p env ps = PipeResult.halt → step cfg p env (absState cfg ps) = StepResult.halt) ∧
∀ (ps' : PipeState cfg) (out : MeshOut cfg.wordBits),
pstep cfg p env ps = PipeResult.next ps' out →
PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = ahs:step cfg p env ps.arch = StepResult.stallh:pstep cfg p env ps = PipeResult.halt⊢ step cfg p env (absState cfg ps) = StepResult.haltcfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = ahs:step cfg p env ps.arch = StepResult.stallps':PipeState cfgout:MeshOut cfg.wordBitsh:pstep cfg p env ps = PipeResult.next ps' out⊢ PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = ahs:step cfg p env ps.arch = StepResult.stallh:pstep cfg p env ps = PipeResult.halt⊢ step cfg p env (absState cfg ps) = StepResult.halt All goals completed! 🐙
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = ahs:step cfg p env ps.arch = StepResult.stallps':PipeState cfgout:MeshOut cfg.wordBitsh:pstep cfg p env ps = PipeResult.next ps' out⊢ PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out) cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = ahs:step cfg p env ps.arch = StepResult.stallps':PipeState cfgout:MeshOut cfg.wordBitsh:ps = ps' ∧ { } = out⊢ PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = ahs:step cfg p env ps.arch = StepResult.stall⊢ PipeInv cfg p ps ∧
(absState cfg ps = absState cfg ps ∧ { } = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps) { })
All goals completed! 🐙
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀⊢ (pstep cfg p env ps = PipeResult.halt → step cfg p env (absState cfg ps) = StepResult.halt) ∧
∀ (ps' : PipeState cfg) (out : MeshOut cfg.wordBits),
pstep cfg p env ps = PipeResult.next ps' out →
PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀h:pstep cfg p env ps = PipeResult.halt⊢ step cfg p env (absState cfg ps) = StepResult.haltcfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀ps':PipeState cfgout:MeshOut cfg.wordBitsh:pstep cfg p env ps = PipeResult.next ps' out⊢ PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀h:pstep cfg p env ps = PipeResult.halt⊢ step cfg p env (absState cfg ps) = StepResult.halt cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀h:(if arch'.pc = ps.arch.pc + 1 then
PipeResult.next { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD } out₀
else PipeResult.next { arch := arch', pcF := arch'.pc, irD := none, irI := none } out₀) =
PipeResult.halt⊢ step cfg p env (absState cfg ps) = StepResult.halt
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀h✝:arch'.pc = ps.arch.pc + 1h:PipeResult.next { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD } out₀ =
PipeResult.halt⊢ step cfg p env (absState cfg ps) = StepResult.haltcfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀h✝:¬arch'.pc = ps.arch.pc + 1h:PipeResult.next { arch := arch', pcF := arch'.pc, irD := none, irI := none } out₀ = PipeResult.halt⊢ step cfg p env (absState cfg ps) = StepResult.halt cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀h✝:arch'.pc = ps.arch.pc + 1h:PipeResult.next { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD } out₀ =
PipeResult.halt⊢ step cfg p env (absState cfg ps) = StepResult.haltcfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀h✝:¬arch'.pc = ps.arch.pc + 1h:PipeResult.next { arch := arch', pcF := arch'.pc, irD := none, irI := none } out₀ = PipeResult.halt⊢ step cfg p env (absState cfg ps) = StepResult.halt All goals completed! 🐙
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀ps':PipeState cfgout:MeshOut cfg.wordBitsh:pstep cfg p env ps = PipeResult.next ps' out⊢ PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out) cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀ps':PipeState cfgout:MeshOut cfg.wordBitsh:(if arch'.pc = ps.arch.pc + 1 then
PipeResult.next { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD } out₀
else PipeResult.next { arch := arch', pcF := arch'.pc, irD := none, irI := none } out₀) =
PipeResult.next ps' out⊢ PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀ps':PipeState cfgout:MeshOut cfg.wordBitsh✝:arch'.pc = ps.arch.pc + 1h:PipeResult.next { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD } out₀ =
PipeResult.next ps' out⊢ PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀ps':PipeState cfgout:MeshOut cfg.wordBitsh✝:¬arch'.pc = ps.arch.pc + 1h:PipeResult.next { arch := arch', pcF := arch'.pc, irD := none, irI := none } out₀ = PipeResult.next ps' out⊢ PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
case isTrue hpc cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀ps':PipeState cfgout:MeshOut cfg.wordBitshpc:arch'.pc = ps.arch.pc + 1h:PipeResult.next { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD } out₀ =
PipeResult.next ps' out⊢ PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀ps':PipeState cfgout:MeshOut cfg.wordBitshpc:arch'.pc = ps.arch.pc + 1h:{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD } = ps' ∧ out₀ = out⊢ PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1⊢ PipeInv cfg p { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD } ∧
(absState cfg { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD } = absState cfg ps ∧
out₀ = { } ∨
step cfg p env (absState cfg ps) =
StepResult.next (absState cfg { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD })
out₀)
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1⊢ PipeInv cfg p { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1⊢ absState cfg { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD } = absState cfg ps ∧
out₀ = { } ∨
step cfg p env (absState cfg ps) =
StepResult.next (absState cfg { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD })
out₀
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1⊢ PipeInv cfg p { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD } cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1⊢ ∀ (a : BitVec 12) (i : Instr),
{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irI = some (a, i) →
i = p a ∧ { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.arch.pc = acfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1⊢ ∀ (a : BitVec 12) (j : Instr),
{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irD = some (a, j) →
j = p a ∧ { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.pcF = a + 1cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1⊢ ∀ (a : BitVec 12) (i : Instr) (b : BitVec 12) (j : Instr),
{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irI = some (a, i) →
{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irD = some (b, j) → b = a + 1cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1⊢ ∀ (a : BitVec 12) (i : Instr),
{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irI = some (a, i) →
{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irD = none →
{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.pcF = a + 1
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1⊢ ∀ (a : BitVec 12) (i : Instr),
{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irI = some (a, i) →
i = p a ∧ { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.arch.pc = a cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1a':BitVec 12i':Instrh':{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irI = some (a', i')⊢ i' = p a' ∧ { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.arch.pc = a'
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1a':BitVec 12i':Instrh':{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irI = some (a', i')hd:i' = p a' ∧ ps.pcF = a' + 1⊢ i' = p a' ∧ { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.arch.pc = a'
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1a':BitVec 12i':Instrh':{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irI = some (a', i')hd:i' = p a' ∧ ps.pcF = a' + 1hsq:a' = a + 1⊢ i' = p a' ∧ { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.arch.pc = a'
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1a':BitVec 12i':Instrh':{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irI = some (a', i')hd:i' = p a' ∧ ps.pcF = a' + 1hsq:a' = a + 1⊢ { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.arch.pc = a'
cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1a':BitVec 12i':Instrh':{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irI = some (a', i')hd:i' = p a' ∧ ps.pcF = a' + 1hsq:a' = a + 1⊢ arch'.pc = a'
All goals completed! 🐙
· left.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1⊢ ∀ (a : BitVec 12) (j : Instr),
{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irD = some (a, j) →
j = p a ∧ { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.pcF = a + 1 intro a' j' h' left.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1a':BitVec 12j':Instrh':{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irD = some (a', j')⊢ j' = p a' ∧ { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.pcF = a' + 1
simp only [Option.some.injEq, Prod.mk.injEq] at h' left.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1a':BitVec 12j':Instrh':ps.pcF = a' ∧ p ps.pcF = j'⊢ j' = p a' ∧ { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.pcF = a' + 1
obtain ⟨rfl, rfl⟩ := h' left.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1⊢ p ps.pcF = p ps.pcF ∧
{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.pcF = ps.pcF + 1
exact ⟨rfl, rfl⟩ All goals completed! 🐙
· left.refine_3 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1⊢ ∀ (a : BitVec 12) (i : Instr) (b : BitVec 12) (j : Instr),
{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irI = some (a, i) →
{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irD = some (b, j) → b = a + 1 intro a' i' b' j' hI' hD' left.refine_3 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1a':BitVec 12i':Instrb':BitVec 12j':InstrhI':{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irI = some (a', i')hD':{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irD = some (b', j')⊢ b' = a' + 1
simp only [Option.some.injEq, Prod.mk.injEq] at hD' left.refine_3 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1a':BitVec 12i':Instrb':BitVec 12j':InstrhI':{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irI = some (a', i')hD':ps.pcF = b' ∧ p ps.pcF = j'⊢ b' = a' + 1
obtain ⟨rfl, _⟩ := hD' left.refine_3 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1a':BitVec 12i':Instrj':InstrhI':{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irI = some (a', i')right✝:p ps.pcF = j'⊢ ps.pcF = a' + 1
exact (hInv.dOk a' i' hI').2 All goals completed! 🐙
· left.refine_4 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1⊢ ∀ (a : BitVec 12) (i : Instr),
{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irI = some (a, i) →
{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irD = none →
{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.pcF = a + 1 intro a' i' hI' hD' left.refine_4 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1a':BitVec 12i':InstrhI':{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irI = some (a', i')hD':{ arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.irD = none⊢ { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }.pcF = a' + 1
simp at hD' All goals completed! 🐙
· right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1⊢ absState cfg { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD } = absState cfg ps ∧
out₀ = { } ∨
step cfg p env (absState cfg ps) =
StepResult.next (absState cfg { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD })
out₀ right right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1⊢ step cfg p env (absState cfg ps) =
StepResult.next (absState cfg { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD })
out₀
rw [habs, right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1⊢ step cfg p env ps.arch =
StepResult.next (absState cfg { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD })
out₀ hs right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1⊢ StepResult.next arch' out₀ =
StepResult.next (absState cfg { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD })
out₀] right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1⊢ StepResult.next arch' out₀ =
StepResult.next (absState cfg { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD })
out₀
congr 1 right.e_s cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1⊢ arch' = absState cfg { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := ps.irD }
cases hD : ps.irD with
| some w => right.e_s.some cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1w:BitVec 12 × InstrhD:ps.irD = some w⊢ arch' = absState cfg { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := some w }
obtain ⟨b, j⟩ := w right.e_s.some cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1b:BitVec 12j:InstrhD:ps.irD = some (b, j)⊢ arch' = absState cfg { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }
simp [absState] All goals completed! 🐙
| none => right.e_s.none cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1hD:ps.irD = none⊢ arch' = absState cfg { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }
have hf := hInv.iSeqF a i hI hD right.e_s.none cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1hD:ps.irD = nonehf:ps.pcF = a + 1⊢ arch' = absState cfg { arch := arch', pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }
simp only [absState] right.e_s.none cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1hD:ps.irD = nonehf:ps.pcF = a + 1⊢ arch' = { pc := ps.pcF, regs := arch'.regs, acc := arch'.acc, scratch := arch'.scratch }
have hpf : ps.pcF = arch'.pc := by cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p ps⊢ (pstep cfg p env ps = PipeResult.halt → step cfg p env (absState cfg ps) = StepResult.halt) ∧
∀ (ps' : PipeState cfg) (out : MeshOut cfg.wordBits),
pstep cfg p env ps = PipeResult.next ps' out →
PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out) rw [hf, cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1hD:ps.irD = nonehf:ps.pcF = a + 1⊢ a + 1 = arch'.pc hpc, cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1hD:ps.irD = nonehf:ps.pcF = a + 1⊢ a + 1 = ps.arch.pc + 1 hio.2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1hD:ps.irD = nonehf:ps.pcF = a + 1⊢ a + 1 = a + 1] right.e_s.none cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1hD:ps.irD = nonehf:ps.pcF = a + 1hpf:ps.pcF = arch'.pc⊢ arch' = { pc := ps.pcF, regs := arch'.regs, acc := arch'.acc, scratch := arch'.scratch }
rw [hpf right.e_s.none cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:arch'.pc = ps.arch.pc + 1hD:ps.irD = nonehf:ps.pcF = a + 1hpf:ps.pcF = arch'.pc⊢ arch' = { pc := arch'.pc, regs := arch'.regs, acc := arch'.acc, scratch := arch'.scratch }] All goals completed! 🐙
case isFalse hpc => cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀ps':PipeState cfgout:MeshOut cfg.wordBitshpc:¬arch'.pc = ps.arch.pc + 1h:PipeResult.next { arch := arch', pcF := arch'.pc, irD := none, irI := none } out₀ = PipeResult.next ps' out⊢ PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
simp only [PipeResult.next.injEq] at h cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀ps':PipeState cfgout:MeshOut cfg.wordBitshpc:¬arch'.pc = ps.arch.pc + 1h:{ arch := arch', pcF := arch'.pc, irD := none, irI := none } = ps' ∧ out₀ = out⊢ PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
obtain ⟨rfl, rfl⟩ := h cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:¬arch'.pc = ps.arch.pc + 1⊢ PipeInv cfg p { arch := arch', pcF := arch'.pc, irD := none, irI := none } ∧
(absState cfg { arch := arch', pcF := arch'.pc, irD := none, irI := none } = absState cfg ps ∧ out₀ = { } ∨
step cfg p env (absState cfg ps) =
StepResult.next (absState cfg { arch := arch', pcF := arch'.pc, irD := none, irI := none }) out₀)
constructor left cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:¬arch'.pc = ps.arch.pc + 1⊢ PipeInv cfg p { arch := arch', pcF := arch'.pc, irD := none, irI := none }right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:¬arch'.pc = ps.arch.pc + 1⊢ absState cfg { arch := arch', pcF := arch'.pc, irD := none, irI := none } = absState cfg ps ∧ out₀ = { } ∨
step cfg p env (absState cfg ps) =
StepResult.next (absState cfg { arch := arch', pcF := arch'.pc, irD := none, irI := none }) out₀
· left cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:¬arch'.pc = ps.arch.pc + 1⊢ PipeInv cfg p { arch := arch', pcF := arch'.pc, irD := none, irI := none } refine ⟨?_, ?_, ?_, ?_⟩ left.refine_1 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:¬arch'.pc = ps.arch.pc + 1⊢ ∀ (a : BitVec 12) (i : Instr),
{ arch := arch', pcF := arch'.pc, irD := none, irI := none }.irI = some (a, i) →
i = p a ∧ { arch := arch', pcF := arch'.pc, irD := none, irI := none }.arch.pc = aleft.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:¬arch'.pc = ps.arch.pc + 1⊢ ∀ (a : BitVec 12) (j : Instr),
{ arch := arch', pcF := arch'.pc, irD := none, irI := none }.irD = some (a, j) →
j = p a ∧ { arch := arch', pcF := arch'.pc, irD := none, irI := none }.pcF = a + 1left.refine_3 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:¬arch'.pc = ps.arch.pc + 1⊢ ∀ (a : BitVec 12) (i : Instr) (b : BitVec 12) (j : Instr),
{ arch := arch', pcF := arch'.pc, irD := none, irI := none }.irI = some (a, i) →
{ arch := arch', pcF := arch'.pc, irD := none, irI := none }.irD = some (b, j) → b = a + 1left.refine_4 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:¬arch'.pc = ps.arch.pc + 1⊢ ∀ (a : BitVec 12) (i : Instr),
{ arch := arch', pcF := arch'.pc, irD := none, irI := none }.irI = some (a, i) →
{ arch := arch', pcF := arch'.pc, irD := none, irI := none }.irD = none →
{ arch := arch', pcF := arch'.pc, irD := none, irI := none }.pcF = a + 1
· left.refine_1 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:¬arch'.pc = ps.arch.pc + 1⊢ ∀ (a : BitVec 12) (i : Instr),
{ arch := arch', pcF := arch'.pc, irD := none, irI := none }.irI = some (a, i) →
i = p a ∧ { arch := arch', pcF := arch'.pc, irD := none, irI := none }.arch.pc = a intro a' i' h' left.refine_1 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:¬arch'.pc = ps.arch.pc + 1a':BitVec 12i':Instrh':{ arch := arch', pcF := arch'.pc, irD := none, irI := none }.irI = some (a', i')⊢ i' = p a' ∧ { arch := arch', pcF := arch'.pc, irD := none, irI := none }.arch.pc = a'; simp at h' All goals completed! 🐙
· left.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:¬arch'.pc = ps.arch.pc + 1⊢ ∀ (a : BitVec 12) (j : Instr),
{ arch := arch', pcF := arch'.pc, irD := none, irI := none }.irD = some (a, j) →
j = p a ∧ { arch := arch', pcF := arch'.pc, irD := none, irI := none }.pcF = a + 1 intro a' j' h' left.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:¬arch'.pc = ps.arch.pc + 1a':BitVec 12j':Instrh':{ arch := arch', pcF := arch'.pc, irD := none, irI := none }.irD = some (a', j')⊢ j' = p a' ∧ { arch := arch', pcF := arch'.pc, irD := none, irI := none }.pcF = a' + 1; simp at h' All goals completed! 🐙
· left.refine_3 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:¬arch'.pc = ps.arch.pc + 1⊢ ∀ (a : BitVec 12) (i : Instr) (b : BitVec 12) (j : Instr),
{ arch := arch', pcF := arch'.pc, irD := none, irI := none }.irI = some (a, i) →
{ arch := arch', pcF := arch'.pc, irD := none, irI := none }.irD = some (b, j) → b = a + 1 intro a' i' b' j' hI' hD' left.refine_3 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:¬arch'.pc = ps.arch.pc + 1a':BitVec 12i':Instrb':BitVec 12j':InstrhI':{ arch := arch', pcF := arch'.pc, irD := none, irI := none }.irI = some (a', i')hD':{ arch := arch', pcF := arch'.pc, irD := none, irI := none }.irD = some (b', j')⊢ b' = a' + 1; simp at hI' All goals completed! 🐙
· left.refine_4 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:¬arch'.pc = ps.arch.pc + 1⊢ ∀ (a : BitVec 12) (i : Instr),
{ arch := arch', pcF := arch'.pc, irD := none, irI := none }.irI = some (a, i) →
{ arch := arch', pcF := arch'.pc, irD := none, irI := none }.irD = none →
{ arch := arch', pcF := arch'.pc, irD := none, irI := none }.pcF = a + 1 intro a' i' hI' hD' left.refine_4 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:¬arch'.pc = ps.arch.pc + 1a':BitVec 12i':InstrhI':{ arch := arch', pcF := arch'.pc, irD := none, irI := none }.irI = some (a', i')hD':{ arch := arch', pcF := arch'.pc, irD := none, irI := none }.irD = none⊢ { arch := arch', pcF := arch'.pc, irD := none, irI := none }.pcF = a' + 1; simp at hI' All goals completed! 🐙
· right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:¬arch'.pc = ps.arch.pc + 1⊢ absState cfg { arch := arch', pcF := arch'.pc, irD := none, irI := none } = absState cfg ps ∧ out₀ = { } ∨
step cfg p env (absState cfg ps) =
StepResult.next (absState cfg { arch := arch', pcF := arch'.pc, irD := none, irI := none }) out₀ right right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:¬arch'.pc = ps.arch.pc + 1⊢ step cfg p env (absState cfg ps) =
StepResult.next (absState cfg { arch := arch', pcF := arch'.pc, irD := none, irI := none }) out₀
rw [habs, right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:¬arch'.pc = ps.arch.pc + 1⊢ step cfg p env ps.arch =
StepResult.next (absState cfg { arch := arch', pcF := arch'.pc, irD := none, irI := none }) out₀ hs right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:¬arch'.pc = ps.arch.pc + 1⊢ StepResult.next arch' out₀ =
StepResult.next (absState cfg { arch := arch', pcF := arch'.pc, irD := none, irI := none }) out₀] right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p psa:BitVec 12i:InstrhI:ps.irI = some (a, i)habs:absState cfg ps = ps.archhio:i = p a ∧ ps.arch.pc = aarch':State cfgout₀:MeshOut cfg.wordBitshs:step cfg p env ps.arch = StepResult.next arch' out₀hpc:¬arch'.pc = ps.arch.pc + 1⊢ StepResult.next arch' out₀ =
StepResult.next (absState cfg { arch := arch', pcF := arch'.pc, irD := none, irI := none }) out₀
congr 1 All goals completed! 🐙
| none => none cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = none⊢ (pstep cfg p env ps = PipeResult.halt → step cfg p env (absState cfg ps) = StepResult.halt) ∧
∀ (ps' : PipeState cfg) (out : MeshOut cfg.wordBits),
pstep cfg p env ps = PipeResult.next ps' out →
PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
cases hD : ps.irD with
| some w => none.some cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonew:BitVec 12 × InstrhD:ps.irD = some w⊢ (pstep cfg p env ps = PipeResult.halt → step cfg p env (absState cfg ps) = StepResult.halt) ∧
∀ (ps' : PipeState cfg) (out : MeshOut cfg.wordBits),
pstep cfg p env ps = PipeResult.next ps' out →
PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
obtain ⟨b, j⟩ := w none.some cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)⊢ (pstep cfg p env ps = PipeResult.halt → step cfg p env (absState cfg ps) = StepResult.halt) ∧
∀ (ps' : PipeState cfg) (out : MeshOut cfg.wordBits),
pstep cfg p env ps = PipeResult.next ps' out →
PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
have hdo := hInv.dOk b j hD none.some cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1⊢ (pstep cfg p env ps = PipeResult.halt → step cfg p env (absState cfg ps) = StepResult.halt) ∧
∀ (ps' : PipeState cfg) (out : MeshOut cfg.wordBits),
pstep cfg p env ps = PipeResult.next ps' out →
PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
have habs : absState cfg ps = { ps.arch with pc := b } := by
simp [absState, hI, hD] none.some cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ (pstep cfg p env ps = PipeResult.halt → step cfg p env (absState cfg ps) = StepResult.halt) ∧
∀ (ps' : PipeState cfg) (out : MeshOut cfg.wordBits),
pstep cfg p env ps = PipeResult.next ps' out →
PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
refine ⟨fun h => ?_, fun ps' out h => ?_⟩ none.some.refine_1 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }h:pstep cfg p env ps = PipeResult.halt⊢ step cfg p env (absState cfg ps) = StepResult.haltnone.some.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }ps':PipeState cfgout:MeshOut cfg.wordBitsh:pstep cfg p env ps = PipeResult.next ps' out⊢ PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
· none.some.refine_1 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }h:pstep cfg p env ps = PipeResult.halt⊢ step cfg p env (absState cfg ps) = StepResult.halt simp [pstep, hI, hD] at h All goals completed! 🐙
· none.some.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }ps':PipeState cfgout:MeshOut cfg.wordBitsh:pstep cfg p env ps = PipeResult.next ps' out⊢ PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out) simp only [pstep, hI, hD, PipeResult.next.injEq] at h none.some.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }ps':PipeState cfgout:MeshOut cfg.wordBitsh:{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) } =
ps' ∧
{ } = out⊢ PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
obtain ⟨rfl, rfl⟩ := h none.some.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ PipeInv cfg p
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) } ∧
(absState cfg
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch },
pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := some (b, j) } =
absState cfg ps ∧
{ } = { } ∨
step cfg p env (absState cfg ps) =
StepResult.next
(absState cfg
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch },
pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := some (b, j) })
{ })
constructor none.some.refine_2.left cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ PipeInv cfg p
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }none.some.refine_2.right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ absState cfg
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) } =
absState cfg ps ∧
{ } = { } ∨
step cfg p env (absState cfg ps) =
StepResult.next
(absState cfg
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) })
{ }
· none.some.refine_2.left cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ PipeInv cfg p
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) } refine ⟨?_, ?_, ?_, ?_⟩ none.some.refine_2.left.refine_1 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ ∀ (a : BitVec 12) (i : Instr),
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.irI =
some (a, i) →
i = p a ∧
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.arch.pc =
anone.some.refine_2.left.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ ∀ (a : BitVec 12) (j_1 : Instr),
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.irD =
some (a, j_1) →
j_1 = p a ∧
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.pcF =
a + 1none.some.refine_2.left.refine_3 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ ∀ (a : BitVec 12) (i : Instr) (b_1 : BitVec 12) (j_1 : Instr),
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.irI =
some (a, i) →
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.irD =
some (b_1, j_1) →
b_1 = a + 1none.some.refine_2.left.refine_4 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ ∀ (a : BitVec 12) (i : Instr),
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.irI =
some (a, i) →
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.irD =
none →
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.pcF =
a + 1
· none.some.refine_2.left.refine_1 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ ∀ (a : BitVec 12) (i : Instr),
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.irI =
some (a, i) →
i = p a ∧
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.arch.pc =
a intro a' i' h' none.some.refine_2.left.refine_1 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }a':BitVec 12i':Instrh':{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.irI =
some (a', i')⊢ i' = p a' ∧
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.arch.pc =
a'
simp only [Option.some.injEq, Prod.mk.injEq] at h' none.some.refine_2.left.refine_1 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }a':BitVec 12i':Instrh':b = a' ∧ j = i'⊢ i' = p a' ∧
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.arch.pc =
a'
obtain ⟨rfl, rfl⟩ := h' none.some.refine_2.left.refine_1 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ j = p b ∧
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.arch.pc =
b
exact ⟨hdo.1, rfl⟩ All goals completed! 🐙
· none.some.refine_2.left.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ ∀ (a : BitVec 12) (j_1 : Instr),
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.irD =
some (a, j_1) →
j_1 = p a ∧
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.pcF =
a + 1 intro a' j' h' none.some.refine_2.left.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }a':BitVec 12j':Instrh':{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.irD =
some (a', j')⊢ j' = p a' ∧
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.pcF =
a' + 1
simp only [Option.some.injEq, Prod.mk.injEq] at h' none.some.refine_2.left.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }a':BitVec 12j':Instrh':ps.pcF = a' ∧ p ps.pcF = j'⊢ j' = p a' ∧
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.pcF =
a' + 1
obtain ⟨rfl, rfl⟩ := h' none.some.refine_2.left.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ p ps.pcF = p ps.pcF ∧
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.pcF =
ps.pcF + 1
exact ⟨rfl, rfl⟩ All goals completed! 🐙
· none.some.refine_2.left.refine_3 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ ∀ (a : BitVec 12) (i : Instr) (b_1 : BitVec 12) (j_1 : Instr),
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.irI =
some (a, i) →
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.irD =
some (b_1, j_1) →
b_1 = a + 1 intro a' i' b' j' hI' hD' none.some.refine_2.left.refine_3 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }a':BitVec 12i':Instrb':BitVec 12j':InstrhI':{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.irI =
some (a', i')hD':{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.irD =
some (b', j')⊢ b' = a' + 1
simp only [Option.some.injEq, Prod.mk.injEq] at hI' hD' none.some.refine_2.left.refine_3 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }a':BitVec 12i':Instrb':BitVec 12j':InstrhI':b = a' ∧ j = i'hD':ps.pcF = b' ∧ p ps.pcF = j'⊢ b' = a' + 1
obtain ⟨rfl, _⟩ := hI' none.some.refine_2.left.refine_3 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }i':Instrb':BitVec 12j':InstrhD':ps.pcF = b' ∧ p ps.pcF = j'right✝:j = i'⊢ b' = b + 1
obtain ⟨rfl, _⟩ := hD' none.some.refine_2.left.refine_3 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }i':Instrj':Instrright✝¹:j = i'right✝:p ps.pcF = j'⊢ ps.pcF = b + 1
exact hdo.2 All goals completed! 🐙
· none.some.refine_2.left.refine_4 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ ∀ (a : BitVec 12) (i : Instr),
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.irI =
some (a, i) →
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.irD =
none →
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.pcF =
a + 1 intro a' i' hI' hD' none.some.refine_2.left.refine_4 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }a':BitVec 12i':InstrhI':{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.irI =
some (a', i')hD':{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.irD =
none⊢ { arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) }.pcF =
a' + 1
simp at hD' All goals completed! 🐙
· none.some.refine_2.right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ absState cfg
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) } =
absState cfg ps ∧
{ } = { } ∨
step cfg p env (absState cfg ps) =
StepResult.next
(absState cfg
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) })
{ } left none.some.refine_2.right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ absState cfg
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) } =
absState cfg ps ∧
{ } = { }
refine ⟨?_, rfl⟩ none.some.refine_2.right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ absState cfg
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) } =
absState cfg ps
rw [habs none.some.refine_2.right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ absState cfg
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) } =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }] none.some.refine_2.right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = noneb:BitVec 12j:InstrhD:ps.irD = some (b, j)hdo:j = p b ∧ ps.pcF = b + 1habs:absState cfg ps =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ absState cfg
{ arch := { pc := b, regs := ps.arch.regs, acc := ps.arch.acc, scratch := ps.arch.scratch }, pcF := ps.pcF + 1,
irD := some (ps.pcF, p ps.pcF), irI := some (b, j) } =
let __src := ps.arch;
{ pc := b, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }
simp [absState] All goals completed! 🐙
| none => none.none cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = none⊢ (pstep cfg p env ps = PipeResult.halt → step cfg p env (absState cfg ps) = StepResult.halt) ∧
∀ (ps' : PipeState cfg) (out : MeshOut cfg.wordBits),
pstep cfg p env ps = PipeResult.next ps' out →
PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
have habs : absState cfg ps = { ps.arch with pc := ps.pcF } := by
simp [absState, hI, hD] none.none cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ (pstep cfg p env ps = PipeResult.halt → step cfg p env (absState cfg ps) = StepResult.halt) ∧
∀ (ps' : PipeState cfg) (out : MeshOut cfg.wordBits),
pstep cfg p env ps = PipeResult.next ps' out →
PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
refine ⟨fun h => ?_, fun ps' out h => ?_⟩ none.none.refine_1 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }h:pstep cfg p env ps = PipeResult.halt⊢ step cfg p env (absState cfg ps) = StepResult.haltnone.none.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }ps':PipeState cfgout:MeshOut cfg.wordBitsh:pstep cfg p env ps = PipeResult.next ps' out⊢ PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
· none.none.refine_1 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }h:pstep cfg p env ps = PipeResult.halt⊢ step cfg p env (absState cfg ps) = StepResult.halt simp [pstep, hI, hD] at h All goals completed! 🐙
· none.none.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }ps':PipeState cfgout:MeshOut cfg.wordBitsh:pstep cfg p env ps = PipeResult.next ps' out⊢ PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out) simp only [pstep, hI, hD, PipeResult.next.injEq] at h none.none.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }ps':PipeState cfgout:MeshOut cfg.wordBitsh:{ arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none } = ps' ∧ { } = out⊢ PipeInv cfg p ps' ∧
(absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out)
obtain ⟨rfl, rfl⟩ := h none.none.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ PipeInv cfg p { arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none } ∧
(absState cfg { arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none } = absState cfg ps ∧
{ } = { } ∨
step cfg p env (absState cfg ps) =
StepResult.next (absState cfg { arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none })
{ })
constructor none.none.refine_2.left cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ PipeInv cfg p { arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }none.none.refine_2.right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ absState cfg { arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none } = absState cfg ps ∧
{ } = { } ∨
step cfg p env (absState cfg ps) =
StepResult.next (absState cfg { arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none })
{ }
· none.none.refine_2.left cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ PipeInv cfg p { arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none } refine ⟨?_, ?_, ?_, ?_⟩ none.none.refine_2.left.refine_1 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ ∀ (a : BitVec 12) (i : Instr),
{ arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.irI = some (a, i) →
i = p a ∧ { arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.arch.pc = anone.none.refine_2.left.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ ∀ (a : BitVec 12) (j : Instr),
{ arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.irD = some (a, j) →
j = p a ∧ { arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.pcF = a + 1none.none.refine_2.left.refine_3 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ ∀ (a : BitVec 12) (i : Instr) (b : BitVec 12) (j : Instr),
{ arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.irI = some (a, i) →
{ arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.irD = some (b, j) → b = a + 1none.none.refine_2.left.refine_4 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ ∀ (a : BitVec 12) (i : Instr),
{ arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.irI = some (a, i) →
{ arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.irD = none →
{ arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.pcF = a + 1
· none.none.refine_2.left.refine_1 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ ∀ (a : BitVec 12) (i : Instr),
{ arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.irI = some (a, i) →
i = p a ∧ { arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.arch.pc = a intro a' i' h' none.none.refine_2.left.refine_1 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }a':BitVec 12i':Instrh':{ arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.irI = some (a', i')⊢ i' = p a' ∧ { arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.arch.pc = a'; simp at h' All goals completed! 🐙
· none.none.refine_2.left.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ ∀ (a : BitVec 12) (j : Instr),
{ arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.irD = some (a, j) →
j = p a ∧ { arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.pcF = a + 1 intro a' j' h' none.none.refine_2.left.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }a':BitVec 12j':Instrh':{ arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.irD = some (a', j')⊢ j' = p a' ∧ { arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.pcF = a' + 1
simp only [Option.some.injEq, Prod.mk.injEq] at h' none.none.refine_2.left.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }a':BitVec 12j':Instrh':ps.pcF = a' ∧ p ps.pcF = j'⊢ j' = p a' ∧ { arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.pcF = a' + 1
obtain ⟨rfl, rfl⟩ := h' none.none.refine_2.left.refine_2 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ p ps.pcF = p ps.pcF ∧
{ arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.pcF = ps.pcF + 1
exact ⟨rfl, rfl⟩ All goals completed! 🐙
· none.none.refine_2.left.refine_3 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ ∀ (a : BitVec 12) (i : Instr) (b : BitVec 12) (j : Instr),
{ arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.irI = some (a, i) →
{ arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.irD = some (b, j) → b = a + 1 intro a' i' b' j' hI' hD' none.none.refine_2.left.refine_3 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }a':BitVec 12i':Instrb':BitVec 12j':InstrhI':{ arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.irI = some (a', i')hD':{ arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.irD = some (b', j')⊢ b' = a' + 1; simp at hI' All goals completed! 🐙
· none.none.refine_2.left.refine_4 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ ∀ (a : BitVec 12) (i : Instr),
{ arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.irI = some (a, i) →
{ arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.irD = none →
{ arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.pcF = a + 1 intro a' i' hI' hD' none.none.refine_2.left.refine_4 cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }a':BitVec 12i':InstrhI':{ arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.irI = some (a', i')hD':{ arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.irD = none⊢ { arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none }.pcF = a' + 1; simp at hI' All goals completed! 🐙
· none.none.refine_2.right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ absState cfg { arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none } = absState cfg ps ∧
{ } = { } ∨
step cfg p env (absState cfg ps) =
StepResult.next (absState cfg { arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none })
{ } left none.none.refine_2.right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ absState cfg { arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none } = absState cfg ps ∧
{ } = { }
refine ⟨?_, rfl⟩ none.none.refine_2.right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ absState cfg { arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none } = absState cfg ps
rw [habs none.none.refine_2.right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ absState cfg { arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none } =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }] none.none.refine_2.right cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfghInv:PipeInv cfg p pshI:ps.irI = nonehD:ps.irD = nonehabs:absState cfg ps =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }⊢ absState cfg { arch := ps.arch, pcF := ps.pcF + 1, irD := some (ps.pcF, p ps.pcF), irI := none } =
let __src := ps.arch;
{ pc := ps.pcF, regs := __src.regs, acc := __src.acc, scratch := __src.scratch }
simp [absState] All goals completed! 🐙
3.7. From one cycle to whole runs
The theorem above is local — one cycle at a time. Correctness of a whole execution follows by induction, and the statement is pleasingly plain: run the pipeline for any number of cycles from power-on, and the state it depicts is exactly what the specification produces after some number of instructions — a number no larger than the cycle count, because a pipeline can lose time to stutters but can never skip ahead, invent work, or fall out of order.
def prunFor (cfg : CoreConfig) (p : Program) (env : MeshIn cfg.wordBits) :
Nat → PipeState cfg → PipeState cfg
| 0, ps => ps
| n + 1, ps =>
match pstep cfg p env ps with
| .next ps' _ => prunFor cfg p env n ps'
| .halt => ps
theorem prun_refines (cfg : CoreConfig) (p : Program) (env : MeshIn cfg.wordBits) :
∀ (n : Nat) (ps : PipeState cfg), PipeInv cfg p ps →
∃ m, m ≤ n ∧
absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps) := by cfg:CoreConfigp:Programenv:MeshIn cfg.wordBits⊢ ∀ (n : Nat) (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)
intro n cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Nat⊢ ∀ (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)
induction n with
| zero => zero cfg:CoreConfigp:Programenv:MeshIn cfg.wordBits⊢ ∀ (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ 0 ∧ absState cfg (prunFor cfg p env 0 ps) = runFor cfg p env m (absState cfg ps)
intro ps _ zero cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsps:PipeState cfga✝:PipeInv cfg p ps⊢ ∃ m, m ≤ 0 ∧ absState cfg (prunFor cfg p env 0 ps) = runFor cfg p env m (absState cfg ps)
exact ⟨0, Nat.le_refl 0, rfl⟩ All goals completed! 🐙
| succ n ih => succ cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Natih:∀ (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)⊢ ∀ (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n + 1 ∧ absState cfg (prunFor cfg p env (n + 1) ps) = runFor cfg p env m (absState cfg ps)
intro ps hInv succ cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Natih:∀ (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)ps:PipeState cfghInv:PipeInv cfg p ps⊢ ∃ m, m ≤ n + 1 ∧ absState cfg (prunFor cfg p env (n + 1) ps) = runFor cfg p env m (absState cfg ps)
cases hp : pstep cfg p env ps with
| halt => succ.halt cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Natih:∀ (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)ps:PipeState cfghInv:PipeInv cfg p pshp:pstep cfg p env ps = PipeResult.halt⊢ ∃ m, m ≤ n + 1 ∧ absState cfg (prunFor cfg p env (n + 1) ps) = runFor cfg p env m (absState cfg ps)
refine ⟨0, Nat.zero_le _, ?_⟩ succ.halt cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Natih:∀ (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)ps:PipeState cfghInv:PipeInv cfg p pshp:pstep cfg p env ps = PipeResult.halt⊢ absState cfg (prunFor cfg p env (n + 1) ps) = runFor cfg p env 0 (absState cfg ps)
simp [prunFor, runFor, hp] All goals completed! 🐙
| next ps' out => succ.next cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Natih:∀ (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)ps:PipeState cfghInv:PipeInv cfg p psps':PipeState cfgout:MeshOut cfg.wordBitshp:pstep cfg p env ps = PipeResult.next ps' out⊢ ∃ m, m ≤ n + 1 ∧ absState cfg (prunFor cfg p env (n + 1) ps) = runFor cfg p env m (absState cfg ps)
obtain ⟨hInv', hcase⟩ := (pstep_refines cfg p env ps hInv).2 ps' out hp succ.next cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Natih:∀ (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)ps:PipeState cfghInv:PipeInv cfg p psps':PipeState cfgout:MeshOut cfg.wordBitshp:pstep cfg p env ps = PipeResult.next ps' outhInv':PipeInv cfg p ps'hcase:absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out⊢ ∃ m, m ≤ n + 1 ∧ absState cfg (prunFor cfg p env (n + 1) ps) = runFor cfg p env m (absState cfg ps)
obtain ⟨m, hm, heq⟩ := ih ps' hInv' succ.next cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Natih:∀ (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)ps:PipeState cfghInv:PipeInv cfg p psps':PipeState cfgout:MeshOut cfg.wordBitshp:pstep cfg p env ps = PipeResult.next ps' outhInv':PipeInv cfg p ps'hcase:absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') outm:Nathm:m ≤ nheq:absState cfg (prunFor cfg p env n ps') = runFor cfg p env m (absState cfg ps')⊢ ∃ m, m ≤ n + 1 ∧ absState cfg (prunFor cfg p env (n + 1) ps) = runFor cfg p env m (absState cfg ps)
have hstep1 : prunFor cfg p env (n + 1) ps = prunFor cfg p env n ps' := by cfg:CoreConfigp:Programenv:MeshIn cfg.wordBits⊢ ∀ (n : Nat) (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)
simp [prunFor, runFor, hp] succ.next cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Natih:∀ (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)ps:PipeState cfghInv:PipeInv cfg p psps':PipeState cfgout:MeshOut cfg.wordBitshp:pstep cfg p env ps = PipeResult.next ps' outhInv':PipeInv cfg p ps'hcase:absState cfg ps' = absState cfg ps ∧ out = { } ∨
step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') outm:Nathm:m ≤ nheq:absState cfg (prunFor cfg p env n ps') = runFor cfg p env m (absState cfg ps')hstep1:prunFor cfg p env (n + 1) ps = prunFor cfg p env n ps'⊢ ∃ m, m ≤ n + 1 ∧ absState cfg (prunFor cfg p env (n + 1) ps) = runFor cfg p env m (absState cfg ps)
cases hcase with
| inl hstut => succ.next.inl cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Natih:∀ (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)ps:PipeState cfghInv:PipeInv cfg p psps':PipeState cfgout:MeshOut cfg.wordBitshp:pstep cfg p env ps = PipeResult.next ps' outhInv':PipeInv cfg p ps'm:Nathm:m ≤ nheq:absState cfg (prunFor cfg p env n ps') = runFor cfg p env m (absState cfg ps')hstep1:prunFor cfg p env (n + 1) ps = prunFor cfg p env n ps'hstut:absState cfg ps' = absState cfg ps ∧ out = { }⊢ ∃ m, m ≤ n + 1 ∧ absState cfg (prunFor cfg p env (n + 1) ps) = runFor cfg p env m (absState cfg ps)
refine ⟨m, Nat.le_succ_of_le hm, ?_⟩ succ.next.inl cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Natih:∀ (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)ps:PipeState cfghInv:PipeInv cfg p psps':PipeState cfgout:MeshOut cfg.wordBitshp:pstep cfg p env ps = PipeResult.next ps' outhInv':PipeInv cfg p ps'm:Nathm:m ≤ nheq:absState cfg (prunFor cfg p env n ps') = runFor cfg p env m (absState cfg ps')hstep1:prunFor cfg p env (n + 1) ps = prunFor cfg p env n ps'hstut:absState cfg ps' = absState cfg ps ∧ out = { }⊢ absState cfg (prunFor cfg p env (n + 1) ps) = runFor cfg p env m (absState cfg ps)
rw [hstep1, succ.next.inl cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Natih:∀ (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)ps:PipeState cfghInv:PipeInv cfg p psps':PipeState cfgout:MeshOut cfg.wordBitshp:pstep cfg p env ps = PipeResult.next ps' outhInv':PipeInv cfg p ps'm:Nathm:m ≤ nheq:absState cfg (prunFor cfg p env n ps') = runFor cfg p env m (absState cfg ps')hstep1:prunFor cfg p env (n + 1) ps = prunFor cfg p env n ps'hstut:absState cfg ps' = absState cfg ps ∧ out = { }⊢ absState cfg (prunFor cfg p env n ps') = runFor cfg p env m (absState cfg ps) heq, succ.next.inl cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Natih:∀ (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)ps:PipeState cfghInv:PipeInv cfg p psps':PipeState cfgout:MeshOut cfg.wordBitshp:pstep cfg p env ps = PipeResult.next ps' outhInv':PipeInv cfg p ps'm:Nathm:m ≤ nheq:absState cfg (prunFor cfg p env n ps') = runFor cfg p env m (absState cfg ps')hstep1:prunFor cfg p env (n + 1) ps = prunFor cfg p env n ps'hstut:absState cfg ps' = absState cfg ps ∧ out = { }⊢ runFor cfg p env m (absState cfg ps') = runFor cfg p env m (absState cfg ps) hstut.1 succ.next.inl cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Natih:∀ (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)ps:PipeState cfghInv:PipeInv cfg p psps':PipeState cfgout:MeshOut cfg.wordBitshp:pstep cfg p env ps = PipeResult.next ps' outhInv':PipeInv cfg p ps'm:Nathm:m ≤ nheq:absState cfg (prunFor cfg p env n ps') = runFor cfg p env m (absState cfg ps')hstep1:prunFor cfg p env (n + 1) ps = prunFor cfg p env n ps'hstut:absState cfg ps' = absState cfg ps ∧ out = { }⊢ runFor cfg p env m (absState cfg ps) = runFor cfg p env m (absState cfg ps)] All goals completed! 🐙
| inr hcommit => succ.next.inr cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Natih:∀ (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)ps:PipeState cfghInv:PipeInv cfg p psps':PipeState cfgout:MeshOut cfg.wordBitshp:pstep cfg p env ps = PipeResult.next ps' outhInv':PipeInv cfg p ps'm:Nathm:m ≤ nheq:absState cfg (prunFor cfg p env n ps') = runFor cfg p env m (absState cfg ps')hstep1:prunFor cfg p env (n + 1) ps = prunFor cfg p env n ps'hcommit:step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out⊢ ∃ m, m ≤ n + 1 ∧ absState cfg (prunFor cfg p env (n + 1) ps) = runFor cfg p env m (absState cfg ps)
refine ⟨m + 1, Nat.succ_le_succ hm, ?_⟩ succ.next.inr cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Natih:∀ (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)ps:PipeState cfghInv:PipeInv cfg p psps':PipeState cfgout:MeshOut cfg.wordBitshp:pstep cfg p env ps = PipeResult.next ps' outhInv':PipeInv cfg p ps'm:Nathm:m ≤ nheq:absState cfg (prunFor cfg p env n ps') = runFor cfg p env m (absState cfg ps')hstep1:prunFor cfg p env (n + 1) ps = prunFor cfg p env n ps'hcommit:step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') out⊢ absState cfg (prunFor cfg p env (n + 1) ps) = runFor cfg p env (m + 1) (absState cfg ps)
have hrun : runFor cfg p env (m + 1) (absState cfg ps)
= runFor cfg p env m (absState cfg ps') := by cfg:CoreConfigp:Programenv:MeshIn cfg.wordBits⊢ ∀ (n : Nat) (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)
simp [runFor, hcommit] succ.next.inr cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Natih:∀ (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)ps:PipeState cfghInv:PipeInv cfg p psps':PipeState cfgout:MeshOut cfg.wordBitshp:pstep cfg p env ps = PipeResult.next ps' outhInv':PipeInv cfg p ps'm:Nathm:m ≤ nheq:absState cfg (prunFor cfg p env n ps') = runFor cfg p env m (absState cfg ps')hstep1:prunFor cfg p env (n + 1) ps = prunFor cfg p env n ps'hcommit:step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') outhrun:runFor cfg p env (m + 1) (absState cfg ps) = runFor cfg p env m (absState cfg ps')⊢ absState cfg (prunFor cfg p env (n + 1) ps) = runFor cfg p env (m + 1) (absState cfg ps)
rw [hstep1, succ.next.inr cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Natih:∀ (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)ps:PipeState cfghInv:PipeInv cfg p psps':PipeState cfgout:MeshOut cfg.wordBitshp:pstep cfg p env ps = PipeResult.next ps' outhInv':PipeInv cfg p ps'm:Nathm:m ≤ nheq:absState cfg (prunFor cfg p env n ps') = runFor cfg p env m (absState cfg ps')hstep1:prunFor cfg p env (n + 1) ps = prunFor cfg p env n ps'hcommit:step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') outhrun:runFor cfg p env (m + 1) (absState cfg ps) = runFor cfg p env m (absState cfg ps')⊢ absState cfg (prunFor cfg p env n ps') = runFor cfg p env (m + 1) (absState cfg ps) heq, succ.next.inr cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Natih:∀ (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)ps:PipeState cfghInv:PipeInv cfg p psps':PipeState cfgout:MeshOut cfg.wordBitshp:pstep cfg p env ps = PipeResult.next ps' outhInv':PipeInv cfg p ps'm:Nathm:m ≤ nheq:absState cfg (prunFor cfg p env n ps') = runFor cfg p env m (absState cfg ps')hstep1:prunFor cfg p env (n + 1) ps = prunFor cfg p env n ps'hcommit:step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') outhrun:runFor cfg p env (m + 1) (absState cfg ps) = runFor cfg p env m (absState cfg ps')⊢ runFor cfg p env m (absState cfg ps') = runFor cfg p env (m + 1) (absState cfg ps) hrun succ.next.inr cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Natih:∀ (ps : PipeState cfg),
PipeInv cfg p ps → ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n ps) = runFor cfg p env m (absState cfg ps)ps:PipeState cfghInv:PipeInv cfg p psps':PipeState cfgout:MeshOut cfg.wordBitshp:pstep cfg p env ps = PipeResult.next ps' outhInv':PipeInv cfg p ps'm:Nathm:m ≤ nheq:absState cfg (prunFor cfg p env n ps') = runFor cfg p env m (absState cfg ps')hstep1:prunFor cfg p env (n + 1) ps = prunFor cfg p env n ps'hcommit:step cfg p env (absState cfg ps) = StepResult.next (absState cfg ps') outhrun:runFor cfg p env (m + 1) (absState cfg ps) = runFor cfg p env m (absState cfg ps')⊢ runFor cfg p env m (absState cfg ps') = runFor cfg p env m (absState cfg ps')] All goals completed! 🐙
theorem pipeline_correct (cfg : CoreConfig) (p : Program)
(env : MeshIn cfg.wordBits) (n : Nat) :
∃ m, m ≤ n ∧
absState cfg (prunFor cfg p env n (PipeState.init cfg))
= runFor cfg p env m (State.init cfg) := by cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Nat⊢ ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n (PipeState.init cfg)) = runFor cfg p env m (State.init cfg)
have h := prun_refines cfg p env n (PipeState.init cfg) (PipeInv.init cfg p) cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Nath:∃ m,
m ≤ n ∧
absState cfg (prunFor cfg p env n (PipeState.init cfg)) = runFor cfg p env m (absState cfg (PipeState.init cfg))⊢ ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n (PipeState.init cfg)) = runFor cfg p env m (State.init cfg)
have habs : absState cfg (PipeState.init cfg) = State.init cfg := by
simp [absState, PipeState.init, State.init] cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Nath:∃ m,
m ≤ n ∧
absState cfg (prunFor cfg p env n (PipeState.init cfg)) = runFor cfg p env m (absState cfg (PipeState.init cfg))habs:absState cfg (PipeState.init cfg) = State.init cfg⊢ ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n (PipeState.init cfg)) = runFor cfg p env m (State.init cfg)
rwa [habs cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Nath:∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n (PipeState.init cfg)) = runFor cfg p env m (State.init cfg)habs:absState cfg (PipeState.init cfg) = State.init cfg⊢ ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n (PipeState.init cfg)) = runFor cfg p env m (State.init cfg)] cfg:CoreConfigp:Programenv:MeshIn cfg.wordBitsn:Nath:∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n (PipeState.init cfg)) = runFor cfg p env m (State.init cfg)habs:absState cfg (PipeState.init cfg) = State.init cfg⊢ ∃ m, m ≤ n ∧ absState cfg (prunFor cfg p env n (PipeState.init cfg)) = runFor cfg p env m (State.init cfg) at h
What the theorem does and does not yet say, honestly. It covers every instruction, every occupancy of the pipeline, and every branch outcome — the squash logic is verified, which was the point. One acknowledged simplification remains: the mailbox environment is held fixed within a cycle-to-instruction comparison; the mesh chapter replaces it with real straps, where the composition makes the correspondence exact.
A simplification we expected to need turns out not to be one. Multiply
hardware often takes more than one clock cycle, and we planned a
bookkeeping extension ("a scoreboard") to track multi-cycle operations.
But look at what the accumulator does to the question: every mac reads
the accumulator that the previous mac wrote, so accumulations are serial
no matter what — there is no parallelism for a scoreboard to recover. If a
future implementation needs two clock cycles for its multiplier, it simply
holds the pipeline for one extra cycle — and an extra held cycle is a
stutter, which is exactly what this chapter's theorem already permits.
The model stays one-instruction-one-step; slower hardware just stutters
more. The refinement absorbs it.
end Tilessa