module Language.Base where open import Data.List as List using (List) open import Data.Nat using (ℕ; suc) open import Data.Product using (Σ; _,_; proj₁) open import Data.String as String using (String) open import Data.Vec using (Vec; foldr; lookup) open import Relation.Binary.PropositionalEquality using (_≡_; refl) open import Lattice data Expr : Set where _+_ : Expr → Expr → Expr _-_ : Expr → Expr → Expr `_ : String → Expr #_ : ℕ → Expr data BasicStmt : Set where _←_ : String → Expr → BasicStmt noop : BasicStmt infixr 2 _then_ infix 3 if_then_else_ infix 3 while_repeat_ data Stmt : Set where ⟨_⟩ : BasicStmt → Stmt _then_ : Stmt → Stmt → Stmt if_then_else_ : Expr → Stmt → Stmt → Stmt while_repeat_ : Expr → Stmt → Stmt data _∈ᵉ_ : String → Expr → Set where in⁺₁ : ∀ {e₁ e₂ : Expr} {k : String} → k ∈ᵉ e₁ → k ∈ᵉ (e₁ + e₂) in⁺₂ : ∀ {e₁ e₂ : Expr} {k : String} → k ∈ᵉ e₂ → k ∈ᵉ (e₁ + e₂) in⁻₁ : ∀ {e₁ e₂ : Expr} {k : String} → k ∈ᵉ e₁ → k ∈ᵉ (e₁ - e₂) in⁻₂ : ∀ {e₁ e₂ : Expr} {k : String} → k ∈ᵉ e₂ → k ∈ᵉ (e₁ - e₂) here : ∀ {k : String} → k ∈ᵉ (` k) data _∈ᵇ_ : String → BasicStmt → Set where in←₁ : ∀ {k : String} {e : Expr} → k ∈ᵇ (k ← e) in←₂ : ∀ {k k' : String} {e : Expr} → k ∈ᵉ e → k ∈ᵇ (k' ← e) open import Lattice.MapSet (String._≟_) renaming ( MapSet to StringSet ; insert to insertˢ ; empty to emptyˢ ; singleton to singletonˢ ; _⊔_ to _⊔ˢ_ ; `_ to `ˢ_ ; _∈_ to _∈ˢ_ ; ⊔-preserves-∈k₁ to ⊔ˢ-preserves-∈k₁ ; ⊔-preserves-∈k₂ to ⊔ˢ-preserves-∈k₂ ) Expr-vars : Expr → StringSet Expr-vars (l + r) = Expr-vars l ⊔ˢ Expr-vars r Expr-vars (l - r) = Expr-vars l ⊔ˢ Expr-vars r Expr-vars (` s) = singletonˢ s Expr-vars (# _) = emptyˢ -- ∈-Expr-vars⇒∈ : ∀ {k : String} (e : Expr) → k ∈ˢ (Expr-vars e) → k ∈ᵉ e -- ∈-Expr-vars⇒∈ {k} (e₁ + e₂) k∈vs -- with Expr-Provenance k ((`ˢ (Expr-vars e₁)) ∪ (`ˢ (Expr-vars e₂))) k∈vs -- ... | in₁ (single k,tt∈vs₁) _ = (in⁺₁ (∈-Expr-vars⇒∈ e₁ (forget k,tt∈vs₁))) -- ... | in₂ _ (single k,tt∈vs₂) = (in⁺₂ (∈-Expr-vars⇒∈ e₂ (forget k,tt∈vs₂))) -- ... | bothᵘ (single k,tt∈vs₁) _ = (in⁺₁ (∈-Expr-vars⇒∈ e₁ (forget k,tt∈vs₁))) -- ∈-Expr-vars⇒∈ {k} (e₁ - e₂) k∈vs -- with Expr-Provenance k ((`ˢ (Expr-vars e₁)) ∪ (`ˢ (Expr-vars e₂))) k∈vs -- ... | in₁ (single k,tt∈vs₁) _ = (in⁻₁ (∈-Expr-vars⇒∈ e₁ (forget k,tt∈vs₁))) -- ... | in₂ _ (single k,tt∈vs₂) = (in⁻₂ (∈-Expr-vars⇒∈ e₂ (forget k,tt∈vs₂))) -- ... | bothᵘ (single k,tt∈vs₁) _ = (in⁻₁ (∈-Expr-vars⇒∈ e₁ (forget k,tt∈vs₁))) -- ∈-Expr-vars⇒∈ {k} (` k) (RelAny.here refl) = here -- ∈⇒∈-Expr-vars : ∀ {k : String} {e : Expr} → k ∈ᵉ e → k ∈ˢ (Expr-vars e) -- ∈⇒∈-Expr-vars {k} {e₁ + e₂} (in⁺₁ k∈e₁) = -- ⊔ˢ-preserves-∈k₁ {m₁ = Expr-vars e₁} -- {m₂ = Expr-vars e₂} -- (∈⇒∈-Expr-vars k∈e₁) -- ∈⇒∈-Expr-vars {k} {e₁ + e₂} (in⁺₂ k∈e₂) = -- ⊔ˢ-preserves-∈k₂ {m₁ = Expr-vars e₁} -- {m₂ = Expr-vars e₂} -- (∈⇒∈-Expr-vars k∈e₂) -- ∈⇒∈-Expr-vars {k} {e₁ - e₂} (in⁻₁ k∈e₁) = -- ⊔ˢ-preserves-∈k₁ {m₁ = Expr-vars e₁} -- {m₂ = Expr-vars e₂} -- (∈⇒∈-Expr-vars k∈e₁) -- ∈⇒∈-Expr-vars {k} {e₁ - e₂} (in⁻₂ k∈e₂) = -- ⊔ˢ-preserves-∈k₂ {m₁ = Expr-vars e₁} -- {m₂ = Expr-vars e₂} -- (∈⇒∈-Expr-vars k∈e₂) -- ∈⇒∈-Expr-vars here = RelAny.here refl BasicStmt-vars : BasicStmt → StringSet BasicStmt-vars (x ← e) = (singletonˢ x) ⊔ˢ (Expr-vars e) BasicStmt-vars noop = emptyˢ Stmt-vars : Stmt → StringSet Stmt-vars ⟨ bs ⟩ = BasicStmt-vars bs Stmt-vars (s₁ then s₂) = (Stmt-vars s₁) ⊔ˢ (Stmt-vars s₂) Stmt-vars (if e then s₁ else s₂) = ((Expr-vars e) ⊔ˢ (Stmt-vars s₁)) ⊔ˢ (Stmt-vars s₂) Stmt-vars (while e repeat s) = (Expr-vars e) ⊔ˢ (Stmt-vars s) -- ∈-Stmt-vars⇒∈ : ∀ {k : String} (s : Stmt) → k ∈ˢ (Stmt-vars s) → k ∈ᵇ s -- ∈-Stmt-vars⇒∈ {k} (k' ← e) k∈vs -- with Expr-Provenance k ((`ˢ (singletonˢ k')) ∪ (`ˢ (Expr-vars e))) k∈vs -- ... | in₁ (single (RelAny.here refl)) _ = in←₁ -- ... | in₂ _ (single k,tt∈vs') = in←₂ (∈-Expr-vars⇒∈ e (forget k,tt∈vs')) -- ... | bothᵘ (single (RelAny.here refl)) _ = in←₁ -- ∈⇒∈-Stmt-vars : ∀ {k : String} {s : Stmt} → k ∈ᵇ s → k ∈ˢ (Stmt-vars s) -- ∈⇒∈-Stmt-vars {k} {k ← e} in←₁ = -- ⊔ˢ-preserves-∈k₁ {m₁ = singletonˢ k} -- {m₂ = Expr-vars e} -- (RelAny.here refl) -- ∈⇒∈-Stmt-vars {k} {k' ← e} (in←₂ k∈e) = -- ⊔ˢ-preserves-∈k₂ {m₁ = singletonˢ k'} -- {m₂ = Expr-vars e} -- (∈⇒∈-Expr-vars k∈e) Stmts-vars : ∀ {n : ℕ} → Vec Stmt n → StringSet Stmts-vars = foldr (λ n → StringSet) (λ {k} stmt acc → (Stmt-vars stmt) ⊔ˢ acc) emptyˢ -- ∈-Stmts-vars⇒∈ : ∀ {n : ℕ} {k : String} (ss : Vec Stmt n) → -- k ∈ˢ (Stmts-vars ss) → Σ (Fin n) (λ f → k ∈ᵇ lookup ss f) -- ∈-Stmts-vars⇒∈ {suc n'} {k} (s ∷ ss') k∈vss -- with Expr-Provenance k ((`ˢ (Stmt-vars s)) ∪ (`ˢ (Stmts-vars ss'))) k∈vss -- ... | in₁ (single k,tt∈vs) _ = (zero , ∈-Stmt-vars⇒∈ s (forget k,tt∈vs)) -- ... | in₂ _ (single k,tt∈vss') = -- let -- (f' , k∈s') = ∈-Stmts-vars⇒∈ ss' (forget k,tt∈vss') -- in -- (suc f' , k∈s') -- ... | bothᵘ (single k,tt∈vs) _ = (zero , ∈-Stmt-vars⇒∈ s (forget k,tt∈vs)) -- ∈⇒∈-Stmts-vars : ∀ {n : ℕ} {k : String} {ss : Vec Stmt n} {f : Fin n} → -- k ∈ᵇ lookup ss f → k ∈ˢ (Stmts-vars ss) -- ∈⇒∈-Stmts-vars {suc n} {k} {s ∷ ss'} {zero} k∈s = -- ⊔ˢ-preserves-∈k₁ {m₁ = Stmt-vars s} -- {m₂ = Stmts-vars ss'} -- (∈⇒∈-Stmt-vars k∈s) -- ∈⇒∈-Stmts-vars {suc n} {k} {s ∷ ss'} {suc f'} k∈ss' = -- ⊔ˢ-preserves-∈k₂ {m₁ = Stmt-vars s} -- {m₂ = Stmts-vars ss'} -- (∈⇒∈-Stmts-vars {n} {k} {ss'} {f'} k∈ss')