Десубстификация и деконгофикация
Oct. 20th, 2015 04:41 pmОчень заманчивая идея о том, как в Agda загнать под капот навязчивые subst и cong.
Пример от автора.
{-# OPTIONS --type-in-type --without-K #-} module russell where open import Data.Product open import Relation.Binary.PropositionalEquality open import Relation.Nullary open import Data.Empty -- a model of set theory data U : Set where set : (I : Set) → (I → U) → U -- a set is regular if it doesn't contain itself regular : U → Set regular (set I f) = (i : I) → ¬ (f i ≡ set I f) -- Russell's set: the set of all regular sets R : U R = set (Σ U regular) proj₁ -- R is not regular R-nonreg : ¬ (regular R) R-nonreg reg = reg (R , reg) refl -- R is regular R-reg : regular R R-reg (x , reg) p = subst regular p reg (x , reg) p -- contradiction absurd : ⊥ absurd = R-nonreg R-regВзято отсюда:
_*_ : ℕ → ℕ → ℕ zero * n = zero suc m * n = n + (m * n)Впрочем внучке стоило бы снять все вопросы, предоставив доказательство
*-commutative : ∀ m n → m * n ≡ n * mВзяв его, например, из Data.Nat.Properties. Или получив самостоятельно.
[true,false,true] : Vec Bool 3 [2,12,85,0,6] : Vec ℕ 5Поясню - я не хочу в этом месте вдаваться в детали описания конструкторов, а скрытый здесь грандиозный обман я честным образом раскрою позже.
{-# IMPORT System.IO #-}а вот так ломается
{-# IMPORT System.IO (hPutStrLn) #-}говоря Parse error (hPutStrLn)
open import Data.Nat
data Fin : ℕ → Set where
fzero : {n : ℕ} → Fin (suc n)
fsuc : {n : ℕ} → Fin n → Fin (suc n)
magic₁ : {A : Set} → Fin zero → A
magic₁ ()
magic₂ : {A : Set} → Fin zero → A
magic₂ n = _
Для того, чтобы правильно сделать коду на Агде грамотную синтаксическую раскраску, требуется не просто полноценно его распарсить, но ещё и повычислять изрядно по ходу дела. То есть ждать приличных внешних тулзов нечего, хочешь цветной Агды - сиди в emacs и не жужжи.agda --html --html-dir=<куда выводить> <корневой модуль>(2) в emacs можно использовать htmlize (или htmlfontify, но у первого, вроде, настройки побогаче).
module AbsurdTest where data False : Set where -- необитаемый record True : Set where -- синглетон data Bool : Set where true : Bool false : Bool -- декодирующая функция для булева универсума isTrue : Bool → Set isTrue true = True isTrue false = False not_ : Bool → Bool not true = false not false = true -- абсурдистская версия lem-not²≡id₁ : (a : Bool) → isTrue (not not a) → isTrue a lem-not²≡id₁ true p = p lem-not²≡id₁ false () -- обывательская версия lem-not²≡id₂ : (a : Bool) → isTrue (not not a) → isTrue a lem-not²≡id₂ true p = p lem-not²≡id₂ false p = pВо второй версии во втором клозе мы спокойно пишем p, хотя его тип isTrue (not not false) редуцируется к необитаемому False.
open import Data.Nat data Fin : ℕ → Set where fzero : {n : ℕ} → Fin (suc n) fsuc : {n : ℕ} → Fin n → Fin (suc n) magic₁ : {A : Set} → Fin zero → A magic₁ () magic₂ : {A : Set} → Fin zero → A magic₂ n = {! !}Если здесь в дырку в magic₂ засунуть _, то нам покрасят его жёлтым, сигнализируя тем самым, что подходящей метапеременной Агде тут не вывести.