{-
This second-order term syntax was created from the following second-order syntax description:

syntax Semiring | SR

type
  * : 0-ary

term
  zero : * | 𝟘
  add  : *  *  ->  * | _βŠ•_ l20
  one  : * | πŸ™
  mult : *  *  ->  * | _βŠ—_ l30

theory
  (𝟘UβŠ•α΄Έ) a |> add (zero, a) = a
  (𝟘UβŠ•α΄Ώ) a |> add (a, zero) = a
  (βŠ•A) a b c |> add (add(a, b), c) = add (a, add(b, c))
  (βŠ•C) a b |> add(a, b) = add(b, a)
  (πŸ™UβŠ—α΄Έ) a |> mult (one, a) = a
  (πŸ™UβŠ—α΄Ώ) a |> mult (a, one) = a
  (βŠ—A) a b c |> mult (mult(a, b), c) = mult (a, mult(b, c))
  (βŠ—DβŠ•α΄Έ) a b c |> mult (a, add (b, c)) = add (mult(a, b), mult(a, c))
  (βŠ—DβŠ•α΄Ώ) a b c |> mult (add (a, b), c) = add (mult(a, c), mult(b, c))
  (𝟘XβŠ—α΄Έ) a |> mult (zero, a) = zero
  (𝟘XβŠ—α΄Ώ) a |> mult (a, zero) = zero
-}


module Semiring.Syntax where

open import SOAS.Common
open import SOAS.Context
open import SOAS.Variable
open import SOAS.Families.Core
open import SOAS.Construction.Structure
open import SOAS.ContextMaps.Inductive

open import SOAS.Metatheory.Syntax

open import Semiring.Signature

private
  variable
    Ξ“ Ξ” Ξ  : Ctx
    Ξ± : *T
    𝔛 : Familyβ‚›

-- Inductive term declaration
module SR:Terms (𝔛 : Familyβ‚›) where

  data SR : Familyβ‚› where
    var  : ℐ β‡ΎΜ£ SR
    mvar : 𝔛 Ξ± Ξ  β†’ Sub SR Ξ  Ξ“ β†’ SR Ξ± Ξ“

    𝟘   : SR * Ξ“
    _βŠ•_ : SR * Ξ“ β†’ SR * Ξ“ β†’ SR * Ξ“
    πŸ™   : SR * Ξ“
    _βŠ—_ : SR * Ξ“ β†’ SR * Ξ“ β†’ SR * Ξ“

  infixl 20 _βŠ•_
  infixl 30 _βŠ—_

  open import SOAS.Metatheory.MetaAlgebra β…€F 𝔛

  SRᡃ : MetaAlg SR
  SRᡃ = record
    { π‘Žπ‘™π‘” = Ξ» where
      (zeroβ‚’ β…‹ _)     β†’ 𝟘
      (addβ‚’  β…‹ a , b) β†’ _βŠ•_ a b
      (oneβ‚’  β…‹ _)     β†’ πŸ™
      (multβ‚’ β…‹ a , b) β†’ _βŠ—_ a b
    ; π‘£π‘Žπ‘Ÿ = var ; π‘šπ‘£π‘Žπ‘Ÿ = Ξ» π”ͺ mΞ΅ β†’ mvar π”ͺ (tabulate mΞ΅) }

  module SRᡃ = MetaAlg SRᡃ

  module _ {π’œ : Familyβ‚›}(π’œα΅ƒ : MetaAlg π’œ) where

    open MetaAlg π’œα΅ƒ

    π•€π•–π•ž : SR β‡ΎΜ£ π’œ
    π•Š : Sub SR Ξ  Ξ“ β†’ Ξ  ~[ π’œ ]↝ Ξ“
    π•Š (t β—‚ Οƒ) new = π•€π•–π•ž t
    π•Š (t β—‚ Οƒ) (old v) = π•Š Οƒ v
    π•€π•–π•ž (mvar π”ͺ mΞ΅) = π‘šπ‘£π‘Žπ‘Ÿ π”ͺ (π•Š mΞ΅)
    π•€π•–π•ž (var v) = π‘£π‘Žπ‘Ÿ v

    π•€π•–π•ž  𝟘        = π‘Žπ‘™π‘” (zeroβ‚’ β…‹ tt)
    π•€π•–π•ž (_βŠ•_ a b) = π‘Žπ‘™π‘” (addβ‚’  β…‹ π•€π•–π•ž a , π•€π•–π•ž b)
    π•€π•–π•ž  πŸ™        = π‘Žπ‘™π‘” (oneβ‚’  β…‹ tt)
    π•€π•–π•ž (_βŠ—_ a b) = π‘Žπ‘™π‘” (multβ‚’ β…‹ π•€π•–π•ž a , π•€π•–π•ž b)

    π•€π•–π•žα΅ƒβ‡’ : MetaAlgβ‡’ SRᡃ π’œα΅ƒ π•€π•–π•ž
    π•€π•–π•žα΅ƒβ‡’ = record
      { βŸ¨π‘Žπ‘™π‘”βŸ© = Ξ»{ {t = t} β†’ βŸ¨π‘Žπ‘™π‘”βŸ© t }
      ; βŸ¨π‘£π‘Žπ‘ŸβŸ© = refl
      ; βŸ¨π‘šπ‘£π‘Žπ‘ŸβŸ© = Ξ»{ {π”ͺ = π”ͺ}{mΞ΅} β†’ cong (π‘šπ‘£π‘Žπ‘Ÿ π”ͺ) (dext (π•Š-tab mΞ΅)) }  }
      where
      open ≑-Reasoning
      βŸ¨π‘Žπ‘™π‘”βŸ© : (t : β…€ SR Ξ± Ξ“) β†’ π•€π•–π•ž (SRᡃ.π‘Žπ‘™π‘” t) ≑ π‘Žπ‘™π‘” (⅀₁ π•€π•–π•ž t)
      βŸ¨π‘Žπ‘™π‘”βŸ© (zeroβ‚’ β…‹ _) = refl
      βŸ¨π‘Žπ‘™π‘”βŸ© (addβ‚’  β…‹ _) = refl
      βŸ¨π‘Žπ‘™π‘”βŸ© (oneβ‚’  β…‹ _) = refl
      βŸ¨π‘Žπ‘™π‘”βŸ© (multβ‚’ β…‹ _) = refl

      π•Š-tab : (mΞ΅ : Ξ  ~[ SR ]↝ Ξ“)(v : ℐ Ξ± Ξ ) β†’ π•Š (tabulate mΞ΅) v ≑ π•€π•–π•ž (mΞ΅ v)
      π•Š-tab mΞ΅ new = refl
      π•Š-tab mΞ΅ (old v) = π•Š-tab (mΞ΅ ∘ old) v

    module _ (g : SR β‡ΎΜ£ π’œ)(gᡃ⇒ : MetaAlgβ‡’ SRᡃ π’œα΅ƒ g) where

      open MetaAlgβ‡’ gᡃ⇒

      π•€π•–π•ž! : (t : SR Ξ± Ξ“) β†’ π•€π•–π•ž t ≑ g t
      π•Š-ix : (mΞ΅ : Sub SR Ξ  Ξ“)(v : ℐ Ξ± Ξ ) β†’ π•Š mΞ΅ v ≑ g (index mΞ΅ v)
      π•Š-ix (x β—‚ mΞ΅) new = π•€π•–π•ž! x
      π•Š-ix (x β—‚ mΞ΅) (old v) = π•Š-ix mΞ΅ v
      π•€π•–π•ž! (mvar π”ͺ mΞ΅) rewrite cong (π‘šπ‘£π‘Žπ‘Ÿ π”ͺ) (dext (π•Š-ix mΞ΅))
        = trans (sym βŸ¨π‘šπ‘£π‘Žπ‘ŸβŸ©) (cong (g ∘ mvar π”ͺ) (tab∘ixβ‰ˆid mΞ΅))
      π•€π•–π•ž! (var v) = sym βŸ¨π‘£π‘Žπ‘ŸβŸ©

      π•€π•–π•ž! 𝟘 = sym βŸ¨π‘Žπ‘™π‘”βŸ©
      π•€π•–π•ž! (_βŠ•_ a b) rewrite π•€π•–π•ž! a | π•€π•–π•ž! b = sym βŸ¨π‘Žπ‘™π‘”βŸ©
      π•€π•–π•ž! πŸ™ = sym βŸ¨π‘Žπ‘™π‘”βŸ©
      π•€π•–π•ž! (_βŠ—_ a b) rewrite π•€π•–π•ž! a | π•€π•–π•ž! b = sym βŸ¨π‘Žπ‘™π‘”βŸ©


-- Syntax instance for the signature
SR:Syn : Syntax
SR:Syn = record
  { β…€F = β…€F
  ; β…€:CS = β…€:CompatStr
  ; mvarα΅’ = SR:Terms.mvar
  ; 𝕋:Init = Ξ» 𝔛 β†’ let open SR:Terms 𝔛 in record
    { βŠ₯ = SR ⋉ SRᡃ
    ; βŠ₯-is-initial = record { ! = Ξ»{ {π’œ ⋉ π’œα΅ƒ} β†’ π•€π•–π•ž π’œα΅ƒ ⋉ π•€π•–π•žα΅ƒβ‡’ π’œα΅ƒ }
    ; !-unique = Ξ»{ {π’œ ⋉ π’œα΅ƒ} (f ⋉ fᡃ⇒) {x = t} β†’ π•€π•–π•ž! π’œα΅ƒ f fᡃ⇒ t } } } }

-- Instantiation of the syntax and metatheory
open Syntax SR:Syn public
open SR:Terms public
open import SOAS.Families.Build public
open import SOAS.Syntax.Shorthands SRᡃ public
open import SOAS.Metatheory SR:Syn public