The messages that player and opponent exchange in the OGS arise from splitting normal forms into the head variable on which it is stuck, an observation, and an assignment. An observation structure axiomatizes theses observations of the language. They consist of:
o_obs
indexed by the types of the language and,In fact as these make sense quite generally, we have already defined them along with generic combinators on sorted families in Ctx/Family.v. Much of the content of this file will be to wrap these generic definitions with more suitable names and provide specific utilities on top.
As explained above, observation structures are just operators. We rename their domain o_dom to just dom.
#[global] Notation obs_struct T C := (Oper T C). #[global] Notation dom := o_dom.
Pointed observations consist of a pair of a variable and a matching observation. We construct them using the generic formal cut combinator on families defined in Ctx/Family.v.
Definition pointed_obs `{CC : context T C} (O : Oper T C) : Fam₀ T C := c_var ∥ₛ ⦉O⦊. #[global] Notation "O ∙" := (pointed_obs O). #[global] Notation m_var o := (o.(cut_l)). #[global] Notation m_obs o := (o.(cut_r)). #[global] Notation m_dom o := (o_dom o.(cut_r)).
Next we define normal forms, as triplets of a variable, an observation and an assignment filling the domain of the observation. For this we again use the formal cut combinator and the "observation filling" combinator, defined in Ctx/Assignment.v.
Definition nf `{CC : context T C} (O : obs_struct T C) (X : Fam₁ T C) : Fam₀ T C
:= c_var ∥ₛ (O # X).
We now define two utilities for projecting normal forms to pointed observations.
Definition nf_to_obs `{CC : context T C} {O} {X : Fam₁ T C} : forall Γ, nf O X Γ -> O∙ Γ := f_cut_map f_id₁ forget_args. #[global] Coercion nf_to_obs : nf >-> pointed_obs. Definition then_to_obs `{CC : context T C} {O} {X : Fam₁ T C} {Γ} : delay (nf O X Γ) -> delay (O∙ Γ) := fmap_delay (nf_to_obs Γ).
Next, we define shortcuts for projecting normal forms into their various components.
Section with_param. Context `{CC : context T C} {O : obs_struct T C} {X : Fam₁ T C}. Definition nf_ty {Γ} (n : nf O X Γ) : T := n.(cut_ty). Definition nf_var {Γ} (n : nf O X Γ) : Γ ∋ nf_ty n := n.(cut_l). Definition nf_obs {Γ} (n : nf O X Γ) : O (nf_ty n) := n.(cut_r).(fill_op). Definition nf_dom {Γ} (n : nf O X Γ) : C := dom n.(cut_r).(fill_op). Definition nf_args {Γ} (n : nf O X Γ) : nf_dom n =[X]> Γ := n.(cut_r).(fill_args).
As normal forms contain an assignment, Coq's equality is not the right notion of equivalence: we wish to consider two normal forms as equivalent even if their assignment are merely pointwise equal.
Variant nf_eq {Γ} : nf O X Γ -> nf O X Γ -> Prop := | NfEq {t} {i : Γ ∋ t} {o a1 a2} : a1 ≡ₐ a2 -> nf_eq (i⋅o⦇a1⦈) (i⋅o⦇a2⦈).T, C: Type
CC: context T C
O: obs_struct T C
X: Fam₁ T C
Γ: CEquivalence nf_eqT, C: Type
CC: context T C
O: obs_struct T C
X: Fam₁ T C
Γ: CEquivalence nf_eqT, C: Type
CC: context T C
O: obs_struct T C
X: Fam₁ T C
Γ: CReflexive nf_eqT, C: Type
CC: context T C
O: obs_struct T C
X: Fam₁ T C
Γ: CSymmetric nf_eqT, C: Type
CC: context T C
O: obs_struct T C
X: Fam₁ T C
Γ: CTransitive nf_eqintros ?; now econstructor.T, C: Type
CC: context T C
O: obs_struct T C
X: Fam₁ T C
Γ: CReflexive nf_eqintros ?? []; now econstructor.T, C: Type
CC: context T C
O: obs_struct T C
X: Fam₁ T C
Γ: CSymmetric nf_eqT, C: Type
CC: context T C
O: obs_struct T C
X: Fam₁ T C
Γ: CTransitive nf_eqeconstructor; now transitivity a2. Qed.T, C: Type
CC: context T C
O: obs_struct T C
X: Fam₁ T C
Γ: C
t: T
i: Γ ∋ t
o: O t
a2, a3: dom o =[ X ]> Γ
H0: a2 ≡ₐ a3
a1: dom o =[ X ]> Γ
H: a1 ≡ₐ a2
y, x: nf O X Γnf_eq (i ⋅ o ⦇ a1 ⦈) (i ⋅ o ⦇ a3 ⦈)
We lift this notion of equivalence to computations returning normal forms.
Definition comp_eq {Γ} : relation (delay (nf O X Γ)) := it_eq (fun _ : T1 => nf_eq) (i := T1_0).T, C: Type
CC: context T C
O: obs_struct T C
X: Fam₁ T C
Γ: CProper (comp_eq ==> it_eq (eqᵢ (fun _ : T1 => O ∙ Γ)) (i:=T1_0)) then_to_obsT, C: Type
CC: context T C
O: obs_struct T C
X: Fam₁ T C
Γ: CProper (comp_eq ==> it_eq (eqᵢ (fun _ : T1 => O ∙ Γ)) (i:=T1_0)) then_to_obsT, C: Type
CC: context T C
O: obs_struct T C
X: Fam₁ T C
Γ: C
a, b: delay (nf O X Γ)
H: it_eq (fun _ : T1 => nf_eq) a bStructure.fmap (fun _ : T1 => nf_to_obs Γ) T1_0 a ≊ Structure.fmap (fun _ : T1 => nf_to_obs Γ) T1_0 bnow intros [] ?? []. Qed. End with_param. #[global] Notation "u ≋ v" := (comp_eq u v).T, C: Type
CC: context T C
O: obs_struct T C
X: Fam₁ T C
Γ: C
a, b: delay (nf O X Γ)
H: it_eq (fun _ : T1 => nf_eq) a bdpointwise_relation (fun i : T1 => ((fun _ : T1 => nf_eq) i ==> eqᵢ (fun _ : T1 => O ∙ Γ) i)%signature) (fun _ : T1 => nf_to_obs Γ) (fun _ : T1 => nf_to_obs Γ)