Skip to content

Commit

Permalink
Proof that PE on concrete inputs is equivalent to concrete eval (#291)
Browse files Browse the repository at this point in the history
Signed-off-by: Craig Disselkoen <cdiss@amazon.com>
  • Loading branch information
cdisselkoen authored May 8, 2024
1 parent 7369309 commit b0310bb
Show file tree
Hide file tree
Showing 19 changed files with 1,216 additions and 32 deletions.
6 changes: 3 additions & 3 deletions cedar-lean/Cedar/Partial/Evaluator.lean
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,9 @@ def evaluateVar (v : Var) (req : Partial.Request) : Result Partial.Value :=
| .principal => .ok req.principal
| .action => .ok req.action
| .resource => .ok req.resource
| .context => match req.context.kvs.mapM λ (k, v) => match v with | .value v => some (k, v) | .residual _ => none with
| some kvs => .ok (.value (Map.make kvs))
| none => .ok (.residual (Partial.Expr.record (req.context.kvs.map fun (k, v) => (k, v.asPartialExpr))))
| .context => match req.context.mapMOnValues λ v => match v with | .value v => some v | .residual _ => none with
| some m => .ok (.value m)
| none => .ok (.residual (Partial.Expr.record (req.context.mapOnValues Partial.Value.asPartialExpr).kvs))

/-- Call an extension function with partial values as arguments -/
def evaluateCall (xfn : ExtFun) (args : List Partial.Value) : Result Partial.Value :=
Expand Down
3 changes: 3 additions & 0 deletions cedar-lean/Cedar/Partial/Value.lean
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,7 @@ def Value.asPartialExpr (v : Partial.Value) : Partial.Expr :=
| .value v => v.asPartialExpr
| .residual r => r

instance : Coe Spec.Value Partial.Value where
coe := Partial.Value.value

end Cedar.Partial
1 change: 1 addition & 0 deletions cedar-lean/Cedar/Thm.lean
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@
-/

import Cedar.Thm.Authorization
import Cedar.Thm.Partial
import Cedar.Thm.Slicing
import Cedar.Thm.Typechecking
28 changes: 14 additions & 14 deletions cedar-lean/Cedar/Thm/Authorization/Authorizer.lean
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ theorem if_hasError_then_exists_error {policy : Policy} {request : Request} {ent
intro h₁
unfold hasError at h₁
split at h₁
case h_1 => simp at h₁
case h_2 err h₂ => exact Exists.intro err h₂
· simp at h₁
· rename_i err _ ; exists err

theorem if_satisfied_then_satisfiedPolicies_non_empty (effect : Effect) (policies : Policies) (request : Request) (entities : Entities) :
(∃ policy,
Expand Down Expand Up @@ -389,9 +389,9 @@ theorem principal_scope_produces_boolean {policy : Policy} {request : Request} {
beq_eq_false_iff_ne, ne_eq, ite_not]
generalize (inₑ request.principal uid entities) = b₁
generalize (ety == request.principal.ty) = b₂
split
case h_1 => trivial
case h_2 h => split at h <;> simp at h
split <;> rename_i h
· trivial
· split at h <;> simp at h

/--
Lemma: evaluating the actionScope of any policy produces a boolean (and does not error)
Expand All @@ -408,9 +408,9 @@ theorem action_scope_produces_boolean {policy : Policy} {request : Request} {ent
simp at h
have h₁ := @action_in_set_of_euids_produces_boolean list request entities
unfold producesBool at h₁
split at h₁
case h_1 _ b h₂ => simp [h₂] at h
case h_2 => simp at h₁
split at h₁ <;> rename_i h₂
· simp [h₂] at h
· simp at h₁
case actionScope scope =>
simp [evaluate, Var.eqEntityUID, Var.inEntityUID, Var.isEntityType, apply₁, apply₂]
cases scope <;> simp [evaluate, apply₁, apply₂, Result.as]
Expand All @@ -419,9 +419,9 @@ theorem action_scope_produces_boolean {policy : Policy} {request : Request} {ent
ne_eq, ite_not]
generalize (inₑ request.action uid entities) = b₁
generalize (ety == request.action.ty) = b₂
split
case h_1 => trivial
case h_2 h => split at h <;> simp at h
split <;> rename_i h
· trivial
· split at h <;> simp at h

/--
Lemma: evaluating the resourceScope of any policy produces a boolean (and does not error)
Expand All @@ -437,9 +437,9 @@ theorem resource_scope_produces_boolean {policy : Policy} {request : Request} {e
beq_eq_false_iff_ne, ne_eq, ite_not]
generalize (inₑ request.resource uid entities) = b₁
generalize (ety == request.resource.ty) = b₂
split
case h_1 => trivial
case h_2 h => split at h <;> simp at h
split <;> rename_i h
· trivial
· split at h <;> simp at h

/--
Lemma: if something produces a boolean, it does not produce a non-boolean
Expand Down
26 changes: 11 additions & 15 deletions cedar-lean/Cedar/Thm/Data/List.lean
Original file line number Diff line number Diff line change
Expand Up @@ -376,18 +376,14 @@ theorem insertCanonical_sortedBy [LT β] [StrictLT β] [DecidableLT β] {f : α
case cons_cons y ys h₄ h₅ =>
specialize ih h₄
simp only [insertCanonical, gt_iff_lt]
split
case inl h₆ =>
apply SortedBy.cons_cons h₃
split <;> rename_i h₆
· apply SortedBy.cons_cons h₃
exact SortedBy.cons_cons h₆ h₄
case inr h₆ =>
split
case inl h₇ =>
apply SortedBy.cons_cons h₅
· split <;> rename_i h₇
· apply SortedBy.cons_cons h₅
simp only [insertCanonical, h₆, ↓reduceIte, gt_iff_lt, h₇] at ih
exact ih
case inr h₇ =>
have h₈ := StrictLT.if_not_lt_gt_then_eq (f x) (f y) h₆ h₇
· have h₈ := StrictLT.if_not_lt_gt_then_eq (f x) (f y) h₆ h₇
apply SortedBy.cons_cons h₃
cases h₄
case cons_nil => exact SortedBy.cons_nil
Expand Down Expand Up @@ -457,8 +453,8 @@ theorem insertCanonical_equiv [LT α] [StrictLT α] [DecidableLT α] (x : α) (x
simp only [id_eq, gt_iff_lt] at ih
have h₃ := insertCanonical_cases id x hd' tl'
simp only [id_eq] at h₃
cases h₃
case inl _ _ _ h₃ =>
cases h₃ <;> rename_i h₃
case inl =>
simp only [h₃]
unfold List.Equiv
simp only [cons_subset, mem_cons, true_or, or_true, true_and]
Expand All @@ -468,9 +464,9 @@ theorem insertCanonical_equiv [LT α] [StrictLT α] [DecidableLT α] (x : α) (x
intro a h₄
simp [h₄]
}
case inr _ _ _ h₃ =>
cases h₃
case inr _ _ _ h₃ =>
case inr =>
cases h₃ <;> rename_i h₃
case inr =>
replace ⟨h₃, h₄, h₅⟩ := h₃
simp only [h₅]
unfold GT.gt at h₄
Expand All @@ -479,7 +475,7 @@ theorem insertCanonical_equiv [LT α] [StrictLT α] [DecidableLT α] (x : α) (x
unfold List.Equiv
simp only [cons_subset, mem_cons, true_or, or_true, Subset.refl, and_self,
subset_cons]
case inl _ _ _ h₃ =>
case inl =>
replace ⟨h₃, h₄, h₅⟩ := h₃
simp only [h₅]
simp only [h₃, h₄] at ih
Expand Down
17 changes: 17 additions & 0 deletions cedar-lean/Cedar/Thm/Partial.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/-
Copyright Cedar Contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-/

import Cedar.Thm.Partial.Evaluation
131 changes: 131 additions & 0 deletions cedar-lean/Cedar/Thm/Partial/Evaluation.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/-
Copyright Cedar Contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-/

import Cedar.Partial.Evaluator
import Cedar.Spec.Evaluator
import Cedar.Thm.Partial.Evaluation.And
import Cedar.Thm.Partial.Evaluation.Basic
import Cedar.Thm.Partial.Evaluation.Binary
import Cedar.Thm.Partial.Evaluation.Call
import Cedar.Thm.Partial.Evaluation.GetAttr
import Cedar.Thm.Partial.Evaluation.HasAttr
import Cedar.Thm.Partial.Evaluation.Ite
import Cedar.Thm.Partial.Evaluation.Or
import Cedar.Thm.Partial.Evaluation.Record
import Cedar.Thm.Partial.Evaluation.Set
import Cedar.Thm.Partial.Evaluation.Unary
import Cedar.Thm.Partial.Evaluation.Var
import Cedar.Thm.Data.Control

/-! This file contains theorems about Cedar's partial evaluator. -/

namespace Cedar.Thm.Partial.Evaluation

open Cedar.Data
open Cedar.Partial (Unknown)
open Cedar.Spec (Error Result)

/--
Partial evaluation with concrete inputs gives the same output as
concrete evaluation with those inputs
-/
theorem on_concrete_eqv_concrete_eval (expr : Spec.Expr) (request : Spec.Request) (entities : Spec.Entities)
(wf : request.WellFormed) :
PartialEvalEquivConcreteEval expr request entities
:= by
unfold PartialEvalEquivConcreteEval
cases expr
case lit p => simp [Partial.evaluate, Spec.evaluate, Spec.Expr.asPartialExpr, Except.map]
case var v =>
have h := Var.on_concrete_eqv_concrete_eval v request entities wf
unfold PartialEvalEquivConcreteEval at h ; exact h
case and x₁ x₂ =>
have ih₁ := on_concrete_eqv_concrete_eval x₁ request entities wf
have ih₂ := on_concrete_eqv_concrete_eval x₂ request entities wf
exact And.on_concrete_eqv_concrete_eval ih₁ ih₂
case or x₁ x₂ =>
have ih₁ := on_concrete_eqv_concrete_eval x₁ request entities wf
have ih₂ := on_concrete_eqv_concrete_eval x₂ request entities wf
exact Or.on_concrete_eqv_concrete_eval ih₁ ih₂
case ite x₁ x₂ x₃ =>
have ih₁ := on_concrete_eqv_concrete_eval x₁ request entities wf
have ih₂ := on_concrete_eqv_concrete_eval x₂ request entities wf
have ih₃ := on_concrete_eqv_concrete_eval x₃ request entities wf
exact Ite.on_concrete_eqv_concrete_eval ih₁ ih₂ ih₃
case unaryApp op x₁ =>
have ih₁ := on_concrete_eqv_concrete_eval x₁ request entities wf
exact Unary.on_concrete_eqv_concrete_eval ih₁
case binaryApp op x₁ x₂ =>
have ih₁ := on_concrete_eqv_concrete_eval x₁ request entities wf
have ih₂ := on_concrete_eqv_concrete_eval x₂ request entities wf
exact Binary.on_concrete_eqv_concrete_eval ih₁ ih₂
case getAttr x₁ attr =>
have ih₁ := on_concrete_eqv_concrete_eval x₁ request entities wf
exact GetAttr.on_concrete_eqv_concrete_eval ih₁
case hasAttr x₁ attr =>
have ih₁ := on_concrete_eqv_concrete_eval x₁ request entities wf
exact HasAttr.on_concrete_eqv_concrete_eval ih₁
case set xs =>
have ih : ∀ x ∈ xs, PartialEvalEquivConcreteEval x request entities := by
intro x h₁
have := List.sizeOf_lt_of_mem h₁
apply on_concrete_eqv_concrete_eval x request entities wf
exact Set.on_concrete_eqv_concrete_eval ih
case record attrs =>
have ih : ∀ kv ∈ attrs, PartialEvalEquivConcreteEval kv.snd request entities := by
intro kv h₁
have := List.sizeOf_lt_of_mem h₁
apply on_concrete_eqv_concrete_eval kv.snd request entities wf
exact Record.on_concrete_eqv_concrete_eval ih
case call xfn args =>
have ih : ∀ arg ∈ args, PartialEvalEquivConcreteEval arg request entities := by
intro arg h₁
have := List.sizeOf_lt_of_mem h₁
apply on_concrete_eqv_concrete_eval arg request entities wf
exact Call.on_concrete_eqv_concrete_eval ih
termination_by expr
decreasing_by
all_goals simp_wf
all_goals try omega
case _ => -- record
have h₂ : sizeOf kv.snd < sizeOf kv := by simp only [sizeOf, Prod._sizeOf_1] ; omega
apply Nat.lt_trans h₂
omega

/--
`Prop` that a given `Result Partial.Value` is either a concrete value or an
error, not a residual
-/
def isValueOrError : Result Partial.Value → Prop
| .ok (.value _) => true
| .ok (.residual _) => false
| .error _ => true

/--
Corollary to the above: partial evaluation with concrete inputs gives a
concrete value (or an error)
-/
theorem on_concrete_gives_concrete (expr : Spec.Expr) (request : Spec.Request) (entities : Spec.Entities)
(wf : request.WellFormed) :
isValueOrError (Partial.evaluate expr request entities)
:= by
rw [on_concrete_eqv_concrete_eval expr request entities wf]
simp only [Except.map, isValueOrError]
split
<;> rename_i h
<;> split at h
<;> simp only [Except.ok.injEq, Except.error.injEq, Partial.Value.value.injEq] at h
<;> trivial
58 changes: 58 additions & 0 deletions cedar-lean/Cedar/Thm/Partial/Evaluation/And.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/-
Copyright Cedar Contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-/

import Cedar.Partial.Evaluator
import Cedar.Spec.Evaluator
import Cedar.Thm.Data.Control
import Cedar.Thm.Partial.Evaluation.Basic

namespace Cedar.Thm.Partial.Evaluation.And

open Cedar.Data
open Cedar.Spec (Result)

/--
Inductive argument that partial evaluating a concrete `Partial.Expr.and`
expression gives the same output as concrete-evaluating the `Spec.Expr.and`
with the same subexpressions
-/
theorem on_concrete_eqv_concrete_eval {x₁ x₂ : Spec.Expr} {request : Spec.Request} {entities : Spec.Entities} :
PartialEvalEquivConcreteEval x₁ request entities →
PartialEvalEquivConcreteEval x₂ request entities →
PartialEvalEquivConcreteEval (Spec.Expr.and x₁ x₂) request entities
:= by
unfold PartialEvalEquivConcreteEval
intro ih₁ ih₂
unfold Partial.evaluate Spec.evaluate Spec.Expr.asPartialExpr
simp only [ih₁, ih₂]
simp only [Except.map, pure, Except.pure, Result.as, Coe.coe]
cases h₁ : Spec.evaluate x₁ request entities <;> simp only [Bool.not_eq_true', Except.bind_err, Except.bind_ok]
case ok v₁ =>
simp only [Spec.Value.asBool]
cases v₁ <;> try simp only [Except.bind_err]
case prim p =>
cases p <;> simp only [Except.bind_ok, Except.bind_err]
case bool b =>
cases b <;> simp only [ite_true, ite_false]
case true =>
split <;> simp only [Except.bind_ok, Except.bind_err]
case h_1 e h₂ => simp only [h₂, Except.bind_err]
case h_2 v h₂ =>
simp only [h₂]
cases v <;> try simp only [Except.bind_err]
case prim p => cases p <;> simp

end Cedar.Thm.Partial.Evaluation.And
Loading

0 comments on commit b0310bb

Please sign in to comment.