Lean source & proof · 43 lines
/-- V is output 3 of the compiled circuit, the port obs-v; the input's initial wires (initial-x, initial-y, initial-z) start at (1, 2, -1) at time = 2. The trajectory decider proved it. Goal (trajectory): trajectory three-state interpretation continuous-real obligation contract start time = 2 initial initial-x = 1, initial-y = 2, initial-z = -1 observe obs-v as V always : V >= 0 and V <= 6 -/
theorem energy_band :
have circuit := Gimle.Forseti.Examples.ThreeStateContract.observed
have time : Gimle.Asgard.Dynamics.TimeDomain := ⟨"time", 2⟩
∀ u : Gimle.Asgard.Dynamics.Signal (0 + 3),
Gimle.Asgard.Dynamics.signalRight u 2 = ![1, 2, -1] →
(∃ y : Gimle.Asgard.Dynamics.Signal 4, circuit.Rel time u y) ∧
(∀ y y' : Gimle.Asgard.Dynamics.Signal 4, circuit.Rel time u y → circuit.Rel time u y' →
∀ t ≥ 2, y t = y' t) ∧
(∀ y : Gimle.Asgard.Dynamics.Signal 4, circuit.Rel time u y →
∀ t ≥ 2, have V := y t 3; V ≥ 0 ∧ V ≤ 6) := by
have root : forsetiRoot := by
unfold forsetiRoot forsetiIdentities forsetiContract
refine ⟨⟨by decide, by decide, by decide⟩, ?_⟩
have time : forsetiTime = Gimle.Asgard.Examples.ThreeState.evolution.time := by simp [forsetiTime, Gimle.Asgard.Model.Evolution.time, Gimle.Asgard.Examples.ThreeState.evolution] <;> norm_num [Rat.mkRat_eq_div]
have init : forsetiInitial = Gimle.Asgard.Examples.ThreeState.model.initial := by rw [Gimle.Asgard.Examples.ThreeState.initial_eq]; funext i; fin_cases i <;> norm_num [forsetiInitial, Rat.mkRat_eq_div]
have obs : forsetiObservation = Gimle.Asgard.Examples.ThreeState.energyIndex := rfl
rw [time, init, obs]
refine Gimle.Forseti.Trajectory.Contract.consequence Gimle.Forseti.Examples.ThreeStateContract.energy_contract (fun _ admitted => admitted) ?_
intro o band t within
have leaf := Gimle.Forseti.Syntax.EntailmentCertificate.sound forsetiLeaf ⟨[⟨⟨[]⟩, [⟨[((mkRat (1) 1), (.constant (mkRat (1) 1)))]⟩, ⟨[]⟩]⟩, ⟨⟨[]⟩, [⟨[]⟩, ⟨[((mkRat (1) 1), (.constant (mkRat (1) 1)))]⟩]⟩]⟩ (by decide +kernel)
apply leaf
simp only [forsetiLeaf, Gimle.Forseti.Syntax.Formula.holds, Gimle.Forseti.Syntax.Relation.holds, Gimle.Asgard.Polynomial.Expr.eval]
obtain ⟨low, high⟩ := band t within
refine ⟨?_, ?_⟩ <;> norm_num [Rat.mkRat_eq_div] <;> linarith
have forsetiCast0 : (((mkRat (6) 1) : ℚ) : ℝ) = 6 := by norm_num [Rat.mkRat_eq_div]
have forsetiCast1 : (((mkRat (2) 1) : ℚ) : ℝ) = 2 := by norm_num [Rat.mkRat_eq_div]
have forsetiCast2 : (((mkRat (1) 1) : ℚ) : ℝ) = 1 := by norm_num [Rat.mkRat_eq_div]
have forsetiCast3 : (((mkRat (-1) 1) : ℚ) : ℝ) = -1 := by norm_num [Rat.mkRat_eq_div]
refine (fun (bridge : _ ↔ forsetiContract) => bridge.mpr (show forsetiIdentities ∧ forsetiContract from root).2) ?_
constructor
· intro claim
unfold forsetiContract
set_option linter.unusedSimpArgs false in simp only [Gimle.Forseti.Trajectory.Realizable, Gimle.Forseti.Trajectory.Unique, Gimle.Forseti.Trajectory.Holds, Gimle.Forseti.Trajectory.Initialized, Gimle.Forseti.Trajectory.Always, Set.EqOn, Gimle.Asgard.Dynamics.TimeDomain.domain, Set.mem_Ici, forsetiTime, forsetiInitial, forsetiPost, forsetiObservation, Gimle.Forseti.Syntax.Formula.holds, Gimle.Forseti.Syntax.Relation.holds, Gimle.Asgard.Polynomial.Expr.eval, true_and, forsetiCast0, forsetiCast1, forsetiCast2, forsetiCast3, ← sub_eq_add_neg, sub_zero, sub_nonpos, sub_neg, sub_eq_zero, sub_nonneg, sub_pos, ge_iff_le, gt_iff_lt, and_assoc, or_assoc] at claim
refine ⟨?_, ?_, ?_⟩ <;> set_option linter.unusedSimpArgs false in simp only [Gimle.Forseti.Trajectory.Realizable, Gimle.Forseti.Trajectory.Unique, Gimle.Forseti.Trajectory.Holds, Gimle.Forseti.Trajectory.Initialized, Gimle.Forseti.Trajectory.Always, Set.EqOn, Gimle.Asgard.Dynamics.TimeDomain.domain, Set.mem_Ici, forsetiTime, forsetiInitial, forsetiPost, forsetiObservation, Gimle.Forseti.Syntax.Formula.holds, Gimle.Forseti.Syntax.Relation.holds, Gimle.Asgard.Polynomial.Expr.eval, true_and, forsetiCast0, forsetiCast1, forsetiCast2, forsetiCast3, ← sub_eq_add_neg, sub_zero, sub_nonpos, sub_neg, sub_eq_zero, sub_nonneg, sub_pos, ge_iff_le, gt_iff_lt, and_assoc, or_assoc]
· exact fun u start => (claim u start).1
· exact fun u start => (claim u start).2.1
· exact fun u start => (claim u start).2.2
· intro lane
unfold forsetiContract at lane
obtain ⟨realizable, unique, holds⟩ := lane
set_option linter.unusedSimpArgs false in simp only [Gimle.Forseti.Trajectory.Realizable, Gimle.Forseti.Trajectory.Unique, Gimle.Forseti.Trajectory.Holds, Gimle.Forseti.Trajectory.Initialized, Gimle.Forseti.Trajectory.Always, Set.EqOn, Gimle.Asgard.Dynamics.TimeDomain.domain, Set.mem_Ici, forsetiTime, forsetiInitial, forsetiPost, forsetiObservation, Gimle.Forseti.Syntax.Formula.holds, Gimle.Forseti.Syntax.Relation.holds, Gimle.Asgard.Polynomial.Expr.eval, true_and, forsetiCast0, forsetiCast1, forsetiCast2, forsetiCast3, ← sub_eq_add_neg, sub_zero, sub_nonpos, sub_neg, sub_eq_zero, sub_nonneg, sub_pos, ge_iff_le, gt_iff_lt, and_assoc, or_assoc] at realizable unique holds ⊢
exact fun u start => ⟨realizable u start, unique u start, holds u start⟩