|
| 1 | +/- |
| 2 | + Copyright Cedar Contributors |
| 3 | +
|
| 4 | + Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | + you may not use this file except in compliance with the License. |
| 6 | + You may obtain a copy of the License at |
| 7 | +
|
| 8 | + https://www.apache.org/licenses/LICENSE-2.0 |
| 9 | +
|
| 10 | + Unless required by applicable law or agreed to in writing, software |
| 11 | + distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | + See the License for the specific language governing permissions and |
| 14 | + limitations under the License. |
| 15 | +-/ |
| 16 | + |
| 17 | + |
| 18 | +import Cedar.TPE |
| 19 | +import Cedar.Spec |
| 20 | +import Cedar.Validation |
| 21 | +import Cedar.Thm.TPE.Input |
| 22 | +import Cedar.Thm.TPE.ErrorFree |
| 23 | +import Cedar.Thm.TPE.WellTyped |
| 24 | +import Cedar.Thm.Validation |
| 25 | +import Cedar.Thm.WellTyped |
| 26 | +import Cedar.Thm.Data.Control |
| 27 | + |
| 28 | +import Cedar.Thm.TPE.Soundness.Basic |
| 29 | + |
| 30 | +namespace Cedar.Thm |
| 31 | + |
| 32 | +open Cedar.Spec |
| 33 | +open Cedar.Validation |
| 34 | +open Cedar.TPE |
| 35 | +open Cedar.Thm |
| 36 | + |
| 37 | +theorem partial_evaluate_is_sound_and |
| 38 | +{x₁ x₂ : Residual} |
| 39 | +{req : Request} |
| 40 | +{es : Entities} |
| 41 | +{preq : PartialRequest} |
| 42 | +{pes : PartialEntities} |
| 43 | +{env : TypeEnv} |
| 44 | +(h₂ : InstanceOfWellFormedEnvironment req es env) |
| 45 | +(h₃ : RequestAndEntitiesRefine req es preq pes) |
| 46 | +(hᵢ₁ : Residual.WellTyped env x₁) |
| 47 | +(hᵢ₂ : Residual.WellTyped env x₂) |
| 48 | +(hᵢ₃ : x₁.typeOf = CedarType.bool BoolType.anyBool) |
| 49 | +(hᵢ₄ : x₂.typeOf = CedarType.bool BoolType.anyBool) |
| 50 | +(hᵢ₅ : Except.toOption (x₁.evaluate req es) = Except.toOption ((TPE.evaluate x₁ preq pes).evaluate req es)) |
| 51 | +(hᵢ₆ : Except.toOption (x₂.evaluate req es) = Except.toOption ((TPE.evaluate x₂ preq pes).evaluate req es)) : |
| 52 | + Except.toOption ((x₁.and x₂ (CedarType.bool BoolType.anyBool)).evaluate req es) = |
| 53 | + Except.toOption ((TPE.evaluate (x₁.and x₂ (CedarType.bool BoolType.anyBool)) preq pes).evaluate req es) |
| 54 | +:= by |
| 55 | + simp [TPE.evaluate, TPE.and] |
| 56 | + split |
| 57 | + case _ ty heq => |
| 58 | + simp [heq, Residual.evaluate] at hᵢ₅ |
| 59 | + have h₅ := to_option_right_ok' hᵢ₅ |
| 60 | + simp [Residual.evaluate, h₅, Result.as, Coe.coe, Value.asBool] |
| 61 | + split |
| 62 | + case _ heq₁ => |
| 63 | + have h₆ := residual_well_typed_is_sound h₂ hᵢ₂ heq₁ |
| 64 | + rw [hᵢ₄] at h₆ |
| 65 | + rcases instance_of_anyBool_is_bool h₆ with ⟨_, h₆⟩ |
| 66 | + replace hᵢ₆ := to_option_left_ok hᵢ₆ heq₁ |
| 67 | + simp only [h₆, Except.map_ok, hᵢ₆] |
| 68 | + case _ heq₁ => |
| 69 | + simp only [Except.map_error] |
| 70 | + rw [heq₁] at hᵢ₆ |
| 71 | + rcases to_option_left_err hᵢ₆ with ⟨_, hᵢ₆⟩ |
| 72 | + simp only [hᵢ₆, Except.toOption] |
| 73 | + case _ heq => |
| 74 | + simp [heq, Residual.evaluate] at hᵢ₅ |
| 75 | + have h₅ := to_option_right_ok' hᵢ₅ |
| 76 | + simp [Residual.evaluate, h₅, Result.as, Coe.coe, Value.asBool, Residual.evaluate] |
| 77 | + case _ heq => |
| 78 | + simp [heq, Residual.evaluate] at hᵢ₅ |
| 79 | + rcases to_option_right_err hᵢ₅ with ⟨_, hᵢ₅⟩ |
| 80 | + simp [Residual.evaluate, hᵢ₅, Result.as, Residual.evaluate, Except.toOption] |
| 81 | + case _ heq _ _ _ => |
| 82 | + simp [heq, Residual.evaluate] at hᵢ₆ |
| 83 | + have h₅ := to_option_right_ok' hᵢ₆ |
| 84 | + simp [Residual.evaluate] |
| 85 | + generalize h₆ : x₁.evaluate req es = res₁ |
| 86 | + cases res₁ |
| 87 | + case ok => |
| 88 | + have h₇ := residual_well_typed_is_sound h₂ hᵢ₁ h₆ |
| 89 | + rw [hᵢ₃] at h₇ |
| 90 | + rcases instance_of_anyBool_is_bool h₇ with ⟨_, h₇⟩ |
| 91 | + simp [h₇, Result.as, Coe.coe, Value.asBool] |
| 92 | + split |
| 93 | + case _ heq₁ => |
| 94 | + subst heq₁ |
| 95 | + rw [h₇] at h₆ |
| 96 | + rw [←h₆] |
| 97 | + exact hᵢ₅ |
| 98 | + case _ heq₁ => |
| 99 | + simp [h₅] |
| 100 | + simp at heq₁ |
| 101 | + subst heq₁ |
| 102 | + subst h₇ |
| 103 | + rw [←h₆] |
| 104 | + exact hᵢ₅ |
| 105 | + case error => |
| 106 | + simp [h₆] at hᵢ₅ |
| 107 | + rcases to_option_left_err hᵢ₅ with ⟨_, hᵢ₅⟩ |
| 108 | + simp only [Except.toOption, Result.as, Except.bind_err, hᵢ₅] |
| 109 | + case _ => |
| 110 | + simp [Residual.evaluate] |
| 111 | + cases h₅ : x₁.evaluate req es |
| 112 | + · simp [Result.as, Except.toOption] |
| 113 | + cases h₆ : (TPE.evaluate x₁ preq pes).errorFree <;> simp |
| 114 | + · split <;> simp |
| 115 | + rename_i h₇ |
| 116 | + simp [Residual.evaluate] at h₇ |
| 117 | + rw [h₅] at hᵢ₅ |
| 118 | + simp [Except.toOption] at hᵢ₅ |
| 119 | + split at hᵢ₅ <;> try contradiction |
| 120 | + clear hᵢ₅ ; rename_i hᵢ₅ |
| 121 | + simp [hᵢ₅, Result.as] at h₇ |
| 122 | + · split <;> simp |
| 123 | + rename_i h₇ |
| 124 | + simp [Residual.evaluate] at h₇ |
| 125 | + subst h₇ |
| 126 | + rw [Residual.error_free_spec] at h₆ |
| 127 | + have h₇ : Residual.WellTyped env (TPE.evaluate x₁ preq pes) := |
| 128 | + partial_eval_preserves_well_typed h₂ h₃ hᵢ₁ |
| 129 | + have h₈ := error_free_evaluate_ok h₂ h₇ h₆ |
| 130 | + simp [Except.isOk, Except.toBool] at h₈ |
| 131 | + split at h₈ <;> try contradiction |
| 132 | + clear h₈ ; rename_i h₈ |
| 133 | + rw [h₅, h₈] at hᵢ₅ |
| 134 | + simp [Except.toOption] at hᵢ₅ |
| 135 | + · simp [Result.as, Except.toOption, Coe.coe, Value.asBool] |
| 136 | + simp [h₅, Except.toOption] at hᵢ₅ |
| 137 | + split at hᵢ₅ <;> try contradiction |
| 138 | + simp at hᵢ₅ |
| 139 | + subst hᵢ₅ |
| 140 | + rename_i hᵢ₅ |
| 141 | + rename_i v _ |
| 142 | + have ⟨_, hv⟩ : ∃ b, v = .prim (.bool b) := by |
| 143 | + have h₇ := residual_well_typed_is_sound h₂ hᵢ₁ h₅ |
| 144 | + rw [hᵢ₃] at h₇ |
| 145 | + exact instance_of_anyBool_is_bool h₇ |
| 146 | + subst hv |
| 147 | + simp only |
| 148 | + rename_i h₁ _ _ _ _ _ |
| 149 | + simp [h₁, Except.toOption, Residual.evaluate] at hᵢ₆ |
| 150 | + split at hᵢ₆ <;> simp at hᵢ₆ |
| 151 | + subst hᵢ₆ |
| 152 | + rename_i hᵢ₆ |
| 153 | + simp [hᵢ₆] |
| 154 | + rename_i b _ |
| 155 | + have hb : (if b = false then (Except.ok (Value.prim (Prim.bool b)) : Except Spec.Error _) else Except.ok (Value.prim (Prim.bool false))) = Except.ok (.prim (.bool false)) := by |
| 156 | + split |
| 157 | + · rename_i hb |
| 158 | + simpa using hb |
| 159 | + · simp |
| 160 | + simp [hb] |
| 161 | + rename_i ty _ _ _ _ _ |
| 162 | + cases he : (TPE.evaluate x₁ preq pes).errorFree<;> simp [Residual.evaluate, hᵢ₅, Result.as, Coe.coe, Value.asBool] |
| 163 | + cases b <;> simp |
| 164 | + case _ => |
| 165 | + simp [Residual.evaluate] |
| 166 | + generalize h₅ : x₁.evaluate req es = res₁ |
| 167 | + cases res₁ |
| 168 | + case ok => |
| 169 | + have h₆ := residual_well_typed_is_sound h₂ hᵢ₁ h₅ |
| 170 | + rw [hᵢ₃] at h₆ |
| 171 | + rcases instance_of_anyBool_is_bool h₆ with ⟨_, h₆⟩ |
| 172 | + subst h₆ |
| 173 | + replace h₅ := to_option_left_ok hᵢ₅ h₅ |
| 174 | + simp [Result.as, Coe.coe, h₅, Value.asBool] |
| 175 | + generalize h₇ : x₂.evaluate req es = res₂ |
| 176 | + cases res₂ |
| 177 | + case _ => |
| 178 | + rw [h₇] at hᵢ₆ |
| 179 | + rcases to_option_left_err hᵢ₆ with ⟨_, hᵢ₆⟩ |
| 180 | + simp [hᵢ₆] |
| 181 | + split <;> simp [Except.toOption] |
| 182 | + case _ => |
| 183 | + replace h₇ := to_option_left_ok hᵢ₆ h₇ |
| 184 | + rw [h₇] |
| 185 | + case error => |
| 186 | + rw [h₅] at hᵢ₅ |
| 187 | + rcases to_option_left_err hᵢ₅ with ⟨_, hᵢ₅⟩ |
| 188 | + simp [Result.as, hᵢ₅, Except.toOption] |
| 189 | + |
| 190 | +end Cedar.Thm |
0 commit comments