module howe where open import Data.Nat open import Data.Vec open import Data.List open import Data.Product import Data.Fin as F import Relation.Binary as B open import Relation.Binary.PropositionalEquality hiding (subst) open import Relation.Nullary module Utils where plus0 : (n : ℕ) → n + 0 ≡ n plus0 zero = refl plus0 (suc n) rewrite plus0 n = refl suc-on-right : (n m : ℕ) → n + suc m ≡ suc (n + m) suc-on-right zero m = refl suc-on-right (suc n) m rewrite suc-on-right n m = refl plus-commute : (n m : ℕ) → n + m ≡ m + n plus-commute zero m rewrite plus0 m = refl plus-commute (suc n) m rewrite suc-on-right m n | plus-commute n m = refl bracket-≤ : {n m : ℕ}(x : ℕ) → n ≤ m → n + x ≤ m + x bracket-≤ {n} {m} zero prf rewrite plus0 n | plus0 m = prf bracket-≤ {n} {m} (suc x) prf rewrite suc-on-right n x | suc-on-right m x = s≤s (bracket-≤ x prf) remove-suc-right : {n m : ℕ} → n ≤ m → n ≤ suc m remove-suc-right z≤n = z≤n remove-suc-right (s≤s prf) = s≤s (remove-suc-right prf) remove-suc-left : {n m : ℕ} → suc n ≤ m → n ≤ m remove-suc-left (s≤s prf) = remove-suc-right prf remove-+-left : {n m x : ℕ} → x + n ≤ m → n ≤ m remove-+-left {n} {m} {zero} prf = prf remove-+-left {n} {m} {suc x} prf = remove-+-left {n}{m}{x} (remove-suc-left {x + n} {m} prf) remove-+-right : {n m x : ℕ} → n + x ≤ m → n ≤ m remove-+-right {n}{m}{x} rewrite plus-commute n x = remove-+-left {n}{m}{x} record LCS : Set₁ where constructor lcs field O : Set Canon : O → Set arity : O → List ℕ data Term (L : LCS) : Set where var : ℕ → Term L op : (o : LCS.O L) → Vec (Term L) (length (LCS.arity L o)) → Term L data WellBound {L : LCS} : ℕ → Term L → Set data WellBoundMany {L : LCS} : {m : ℕ} → ℕ → ℕ → Vec (Term L) m → Set data WellBound {L : LCS} where var : {n m : ℕ} → n < m → WellBound m (var n) op : (o : LCS.O L){m : ℕ}(args : Vec (Term L) (length (LCS.arity L o))) → WellBoundMany 0 m args → WellBound m (op o args) data WellBoundMany {L : LCS} where nil : {k n : ℕ} → WellBoundMany k n [] cons : {k n m : ℕ}(h : Term L)(rest : Vec (Term L) m) → WellBound (n + k) h → WellBoundMany (suc k) n rest → WellBoundMany k n (h ∷ rest) Closed : {L : LCS} → Term L → Set Closed = WellBound 0 mutual well-bound-weaken : {L : LCS}{n m : ℕ}{t : Term L} → n ≤ m → WellBound n t → WellBound m t well-bound-weaken prf (var x) = var (B.IsPartialOrder.trans (B.IsTotalOrder.isPartialOrder (B.IsDecTotalOrder.isTotalOrder (B.DecTotalOrder.isDecTotalOrder decTotalOrder))) x prf) well-bound-weaken prf (op o args x) = op o args (well-bound-many-weaken prf x) well-bound-many-weaken : {L : LCS}{n m k len : ℕ}{v : Vec (Term L) len} → n ≤ m → WellBoundMany k n v → WellBoundMany k m v well-bound-many-weaken prf nil = nil well-bound-many-weaken {k = k} prf (cons _ _ x wbm) = cons _ _ (well-bound-weaken (Utils.bracket-≤ k prf) x) (well-bound-many-weaken prf wbm) data IsCanon {L : LCS} : Term L → Set where op : {o : LCS.O L}(args : _) → LCS.Canon L o → IsCanon (op o args) record Eval (L : LCS) : Set₁ where constructor eval field _⇓_ : Term L → Term L → Set steps : ℕ → Term L → Term L → Set -- Expected properties of a stepping relation eval-to-canon : {t t' : Term L} → t ⇓ t' → IsCanon t' canon-to-canon : {t : Term L} → IsCanon t → t ⇓ t deterministic : {t t₁ t₂ : Term L} → t ⇓ t₁ → t ⇓ t₂ → t₁ ≡ t₂ -- Indexed steps steps-eventually : {t t' : Term L} → t ⇓ t' → Σ ℕ λ n → steps n t t' steps-agrees : {t t' : Term L}{n : ℕ} → steps n t t' → t ⇓ t' mutual -- This relies on the fact that we only ever substitute closed terms subst : {L : LCS} → Term L → ℕ → Term L → Term L subst new n (var x) with compare x n ... | less .x k = var x ... | equal .n = new ... | greater .n k = var (n + k) subst {L} new n (op o args) = op o (subst-many 0 new n args) subst-many : {L : LCS}{n : ℕ} → ℕ → Term L → ℕ → Vec (Term L) n → Vec (Term L) n subst-many m new n [] = [] subst-many m new n (x ∷ v) = subst new (n + m) x ∷ subst-many (suc m) new n v mutual subst-closes : {L : LCS}{n x : ℕ}(t t' : Term L) → x < n → WellBound (suc n) t → Closed t' → WellBound n (subst t' x t) subst-closes {x = x} .(var n) t' x