У меня возникли трудности с убеждением Agda в завершении проверки функции fmap
ниже и аналогичных функций, определенных рекурсивно над структурой Trie
. A Trie
- это номер trie, домен которого Type
, тип уровня объекта, сформированный из единицы, продуктов и неподвижных точек (я пропустил сопроводительные материалы, чтобы сохранить код минимальным). Проблема, похоже, связана с заменой типа уровня, которую я использую в определении Trie
. (Выражение const (μₜ τ) * τ
средством применить замену const (μₜ τ)
к типу τ
.)Прекращение проверки функции по trie
module Temp where
open import Data.Unit
open import Category.Functor
open import Function
open import Level
open import Relation.Binary
-- A context is just a snoc-list.
data Cxt {} (A : Set) : Set where
ε : Cxt A
_∷ᵣ_ : Cxt A → A → Cxt A
-- Context membership.
data _∈_ {} {A : Set } (a : A) : Cxt A → Set where
here : ∀ {Δ} → a ∈ Δ ∷ᵣ a
there : ∀ {Δ a′} → a ∈ Δ → a ∈ Δ ∷ᵣ a′
infix 3 _∈_
-- Well-formed types, using de Bruijn indices.
data _⊦ (Δ : Cxt ⊤) : Set where
nat : Δ ⊦
: Δ ⊦
var : _ ∈ Δ → Δ ⊦
_+_ _⨰_ : Δ ⊦ → Δ ⊦ → Δ ⊦
μ : Δ ∷ᵣ _ ⊦ → Δ ⊦
infix 3 _⊦
-- A closed type.
Type : Set
Type = ε ⊦
-- Type-level substitutions and renamings.
Sub Ren : Rel (Cxt ⊤) zero
Sub Δ Δ′ = _ ∈ Δ → Δ′ ⊦
Ren Δ Δ′ = ∀ {x} → x ∈ Δ → x ∈ Δ′
-- Renaming extension.
extendᵣ : ∀ {Δ Δ′} → Ren Δ Δ′ → Ren (Δ ∷ᵣ _) (Δ′ ∷ᵣ _)
extendᵣ ρ here = here
extendᵣ ρ (there x) = there (ρ x)
-- Lift a type renaming to a type.
_*ᵣ_ : ∀ {Δ Δ′} → Ren Δ Δ′ → Δ ⊦ → Δ′ ⊦
_ *ᵣ nat = nat
_ *ᵣ =
ρ *ᵣ (var x) = var (ρ x)
ρ *ᵣ (τ₁ + τ₂) = (ρ *ᵣ τ₁) + (ρ *ᵣ τ₂)
ρ *ᵣ (τ₁ ⨰ τ₂) = (ρ *ᵣ τ₁) ⨰ (ρ *ᵣ τ₂)
ρ *ᵣ (μ τ) = μ (extendᵣ ρ *ᵣ τ)
-- Substitution extension.
extend : ∀ {Δ Δ′} → Sub Δ Δ′ → Sub (Δ ∷ᵣ _) (Δ′ ∷ᵣ _)
extend θ here = var here
extend θ (there x) = there *ᵣ (θ x)
-- Lift a type substitution to a type.
_*_ : ∀ {Δ Δ′} → Sub Δ Δ′ → Δ ⊦ → Δ′ ⊦
θ * nat = nat
θ * =
θ * var x = θ x
θ * (τ₁ + τ₂) = (θ * τ₁) + (θ * τ₂)
θ * (τ₁ ⨰ τ₂) = (θ * τ₁) ⨰ (θ * τ₂)
θ * μ τ = μ (extend θ * τ)
data Trie {} (A : Set) : Type → Set where
〈〉 : A → ▷ A
〔_,_〕 : ∀ {τ₁ τ₂} → τ₁ ▷ A → τ₂ ▷ A → τ₁ + τ₂ ▷ A
↑_ : ∀ {τ₁ τ₂} → τ₁ ▷ τ₂ ▷ A → τ₁ ⨰ τ₂ ▷ A
roll : ∀ {τ} → (const (μ τ) * τ) ▷ A → μ τ ▷ A
infixr 5 Trie
syntax Trie A τ = τ ▷ A
{-# NO_TERMINATION_CHECK #-}
fmap : ∀ {a} {A B : Set a} {τ} → (A → B) → τ ▷ A → τ ▷ B
fmap f (〈〉 x) = 〈〉 (f x)
fmap f 〔 σ₁ , σ₂ 〕 = 〔 fmap f σ₁ , fmap f σ₂ 〕
fmap f (↑ σ) = ↑ (fmap (fmap f) σ)
fmap f (roll σ) = roll (fmap f σ)
Казалось бы, что fmap
рекурсивно в строго меньшего аргумента в каждом случае; конечно, случай продукта прекрасен, если я удаляю рекурсивные типы. С другой стороны, определение обрабатывает рекурсивные типы, если я удаляю продукты.
Что является самым простым способом здесь? inline/fuse trick не выглядит особенно применимым, но, возможно, это так. Или я должен искать другой способ справиться с заменой в определении Trie
?
Похоже, некоторые из вашего юникода теряется :( – copumpkin
Ах, не на моей установке Ubuntu;) Скажите мне, где они есть. символов, которые вы не видите, и я попытаюсь опубликовать более дружественную версию. (Интересно, это специальные символы шрифта?) – Roly
Я имел в виду «символы букв», а не «символы шрифта». – Roly