[Agda] Proving properties about a datatype with a functional component

Shin-Cheng Mu scm at iis.sinica.edu.tw
Wed Sep 26 11:18:34 CEST 2018


Hi,

This is a question that might be related to extensional equality,
and perhaps more. I believe that similar questions must have been
raised in other contexts, but I cannot not find solutions that
work in this case, and therefore decided to pose the question to
the list.

In a simplified form, a "responsive computation" of type A is 
either a value of type A, or a function that takes a signal
from the environment (for example, a Nat, indicating perhaps the
current time) and returns a responsive computation. This can
be modelled by the datatype:

  data RComp (A : Set) : Set where
    V : A → RComp A
    R : (ℕ → RComp A) → RComp A

I wish to prove various operations on RComp, as well as 
proving their properties. For example, we can define an 
"fmap" function for RComp:

  fmap : {A B : Set} → (A → B) → RComp A → RComp B
  fmap f (V x) = V (f x)
  fmap f (R k) = R (fmap f ∘ k)

(The definition passes termination check in Agda 2.5.4.1,
but not in, say, 2.5.2.)

One of the things I wish I can do is to prove that fmap 
is indeed a functorial map. For example, we shall have, 
for all x, fmap id x = x:

  functor1 : ∀ {A} (x : RComp A) → fmap id x ≡ x
  functor1 (V x) = refl
  functor1 (R k) = ?   -- goal: R (fmap id ∘ k) = R k

The base case (V x) is immediate. For the inductive case,
we need to prove 

  R (fmap id ∘ k) = R k

One might try either:
  
  functor1 (R k) = cong R ?                 -- goal: (fmap id ∘ k) ≡ k
  functor1 (R k) = cong (λ g → R (g ∘ k)) ? -- goal: fmap id ≡ id

Either way, extensional equality seems to start being
involved. 

I am not sure about the consequences if I postulate
extensionality. Anyway, if I do:

  postulate
    extensionality :
     {A B : Set} {f g : A → B} → (∀ x → f x ≡ g x) → f ≡ g

I can get the following to type check (where extensionality
is used to convert the recursive call to fmap id ≡ id), 

  functor1 : ∀ {A} (x : RComp A) → fmap id x ≡ x
  functor1 (V x) = refl
  functor1 {A} (R k) = cong (λ g → R (g ∘ k)) ext
    where ext : fmap {A} {A} id ≡ id
          ext = extensionality (functor1 {A})

but this fails termination check.

My question is: how would you formulate this scenario 
and prove the property above?

* Is it okay to postulate extensional equality? 
  I read about some consequences, including losing 
  canonicity, etc. Does that matter to what I want
  to prove, if they are mostly like the functorial
  property above?

* To get around the termination check, is it a 
  wrong idea to formulate RComp as an inductive type? 
  Do I need coinductive type, or the delay monad, or..?

Thank you!

(some test code is attached below)

sincerely, 
Shin
scm at iis.sinica.edu.tw


-----

module RComp where

open import Data.Nat  -- only as an example
open import Relation.Binary.PropositionalEquality

data RComp (A : Set) : Set where
  V : A → RComp A
  R : (ℕ → RComp A) → RComp A

_∘_ : {A B C : Set} → (B → C) → (A → B) → A → C
(f ∘ g) x = f (g x)

fmap : {A B : Set} → (A → B) → RComp A → RComp B
fmap f (V x) = V (f x)
fmap f (R k) = R (fmap f ∘ k)

id : {A : Set} → A → A
id x = x

postulate
  extensionality :
   {A B : Set} {f g : A → B} → (∀ x → f x ≡ g x) → f ≡ g

{-# TERMINATING #-}  -- the following fails termination check
functor1 : ∀ {A} (x : RComp A) → fmap id x ≡ x
functor1 (V x) = refl
functor1 {A} (R k) = cong (λ g → R (g ∘ k)) ext
  where ext : fmap {A} {A} id ≡ id
        ext = extensionality (functor1 {A})



More information about the Agda mailing list