@@ -563,6 +563,108 @@ def execForEachLoop
563563 | .return value next => .return value next
564564 | .revert => .revert
565565
566+ @[simp] theorem execForEachLoop_zero
567+ (varName : String)
568+ (runBody : RuntimeState → StmtResult)
569+ (state : RuntimeState)
570+ (index : Nat) :
571+ execForEachLoop varName runBody state index 0 = .continue state := rfl
572+
573+ theorem execForEachLoop_succ
574+ (varName : String)
575+ (runBody : RuntimeState → StmtResult)
576+ (state : RuntimeState)
577+ (index remaining : Nat) :
578+ execForEachLoop varName runBody state index (remaining + 1 ) =
579+ let loopState :=
580+ { state with bindings := bindValue state.bindings varName (wordNormalize index) }
581+ match runBody loopState with
582+ | .continue next => execForEachLoop varName runBody next (index + 1 ) remaining
583+ | .stop next => .stop next
584+ | .return value next => .return value next
585+ | .revert => .revert := rfl
586+
587+ @[simp] theorem lookupBinding?_bindValue_same
588+ (bindings : List (String × Nat))
589+ (name : String)
590+ (value : Nat) :
591+ lookupBinding? (bindValue bindings name value) name = some value := by
592+ simp [lookupBinding?, bindValue]
593+
594+ @[simp] theorem lookupValue_bindValue_same
595+ (bindings : List (String × Nat))
596+ (name : String)
597+ (value : Nat) :
598+ lookupValue (bindValue bindings name value) name = value := by
599+ simp [lookupValue, bindValue]
600+
601+ @[simp] theorem execForEachLoop_boundState_lookupBinding?
602+ (varName : String)
603+ (state : RuntimeState)
604+ (index : Nat) :
605+ lookupBinding?
606+ (bindValue state.bindings varName (wordNormalize index))
607+ varName =
608+ some (wordNormalize index) := by
609+ simp
610+
611+ @[simp] theorem execForEachLoop_boundState_lookupValue
612+ (varName : String)
613+ (state : RuntimeState)
614+ (index : Nat) :
615+ lookupValue
616+ (bindValue state.bindings varName (wordNormalize index))
617+ varName =
618+ wordNormalize index := by
619+ simp
620+
621+ theorem execForEachLoop_zero_continue_state
622+ {varName : String}
623+ {runBody : RuntimeState → StmtResult}
624+ {state final : RuntimeState}
625+ {index : Nat}
626+ (hloop : execForEachLoop varName runBody state index 0 = .continue final) :
627+ final = state := by
628+ simpa [execForEachLoop] using hloop.symm
629+
630+ theorem execForEachLoop_succ_continue_iff
631+ {varName : String}
632+ {runBody : RuntimeState → StmtResult}
633+ {state final : RuntimeState}
634+ {index remaining : Nat} :
635+ execForEachLoop varName runBody state index (remaining + 1 ) = .continue final ↔
636+ ∃ next,
637+ runBody
638+ { state with
639+ bindings := bindValue state.bindings varName (wordNormalize index) } =
640+ .continue next ∧
641+ execForEachLoop varName runBody next (index + 1 ) remaining =
642+ .continue final := by
643+ simp only [execForEachLoop]
644+ cases hbody :
645+ runBody
646+ { state with
647+ bindings := bindValue state.bindings varName (wordNormalize index) } <;>
648+ simp [hbody]
649+
650+ theorem execForEachLoop_succ_continue
651+ {varName : String}
652+ {runBody : RuntimeState → StmtResult}
653+ {state next final : RuntimeState}
654+ {index remaining : Nat}
655+ (hbody :
656+ runBody
657+ { state with
658+ bindings := bindValue state.bindings varName (wordNormalize index) } =
659+ .continue next)
660+ (hloop :
661+ execForEachLoop varName runBody next (index + 1 ) remaining =
662+ .continue final) :
663+ execForEachLoop varName runBody state index (remaining + 1 ) =
664+ .continue final := by
665+ rw [execForEachLoop_succ]
666+ simpa only [hbody] using hloop
667+
566668theorem execForEachLoop_congr
567669 {varName : String}
568670 {runBodyA runBodyB : RuntimeState → StmtResult}
0 commit comments