Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Nicola Botta
papers
Commits
b4e5227f
Commit
b4e5227f
authored
Mar 08, 2021
by
Nicola Botta
Browse files
Sync with unshared/manuscripts/2020.exteqaxiom before submission.
parent
797174ed
Changes
9
Hide whitespace changes
Inline
Side-by-side
2020.Extensional equality preservation and verified generic programming/About.lidr
View file @
b4e5227f
...
@@ -106,7 +106,7 @@ The proof uses pattern matching, which is straightforward here because
...
@@ -106,7 +106,7 @@ The proof uses pattern matching, which is straightforward here because
%endif
%endif
%
%
In a similar way, one can prove that |(=)| is an equivalence relation:
In a similar way, one can prove that |(=)| is an equivalence relation:
R
eflexivity is directly implemented by |Refl|, while symmetry and
r
eflexivity is directly implemented by |Refl|, while symmetry and
transitivity can be proven by pattern matching.
transitivity can be proven by pattern matching.
...
@@ -160,9 +160,10 @@ but not the converse, normally referred to as \emph{function extensionality}:
...
@@ -160,9 +160,10 @@ but not the converse, normally referred to as \emph{function extensionality}:
When working with functions, extensional equality is often the notion of
When working with functions, extensional equality is often the notion of
interest and libraries of formalized mathematics typically provide
interest and libraries of formalized mathematics typically provide
definitions like |<=>| and basic results like |IEqImplEE|, see for
definitions like |<=>| and basic results like |IEqImplEE|.
example |homot| and |eqtohomot| in Part A of the UniMath library \citep{UniMath}
%
or |eqfun| in Coq \citep{CoqProofAssistant}.
See for example |homot| and |eqtohomot| in Part A of the UniMath
library \citep{UniMath} or |eqfun| in Coq \citep{CoqProofAssistant}.
In reasoning about generic programs in the style of the Algebra of
In reasoning about generic programs in the style of the Algebra of
Programming \citep{DBLP:books/daglib/0096998,mu2009algebra} and, more
Programming \citep{DBLP:books/daglib/0096998,mu2009algebra} and, more
...
@@ -200,7 +201,7 @@ two-argument version of extensional equality preservation:
...
@@ -200,7 +201,7 @@ two-argument version of extensional equality preservation:
> compPresEE : {A, B, C : Type} -> {g, g' : B -> C} -> {f, f' : A -> B} ->
> compPresEE : {A, B, C : Type} -> {g, g' : B -> C} -> {f, f' : A -> B} ->
> g <=> g' -> f <=> f' -> g . f <=> g' . f'
> g <=> g' -> f <=> f' -> g . f <=> g' . f'
> compPresEE {g} {g'} {f} {f'} gExtEq
fExtEq
x =
> compPresEE {g} {g'} {f} {f'} gExtEq
{-"\ "-} fExtEq {-"\ "-}
x =
> ( (g . f) x ) ={ Refl }=
> ( (g . f) x ) ={ Refl }=
> ( g (f x) ) ={ cong (fExtEq x) }=
> ( g (f x) ) ={ cong (fExtEq x) }=
> ( g (f' x) ) ={ gExtEq (f' x) }=
> ( g (f' x) ) ={ gExtEq (f' x) }=
...
@@ -209,8 +210,8 @@ two-argument version of extensional equality preservation:
...
@@ -209,8 +210,8 @@ two-argument version of extensional equality preservation:
The right hand side is a chain of equal expressions connected by the
The right hand side is a chain of equal expressions connected by the
|={| proofs |}=| of the individual steps within special braces and
|={| proofs |}=| of the individual steps within special braces and
ending in |QED|, see ``Preorder reasoning'' in
ending in |QED|, see ``Preorder reasoning'' in
the documentation by
\cite
p
{idrisdocs}.
\cite
t
{idrisdocs}.
%
%
The steps with |Refl| are just for human readability, they could be
The steps with |Refl| are just for human readability, they could be
omitted as far as Idris is concerned.
omitted as far as Idris is concerned.
...
@@ -243,10 +244,10 @@ This paper is also about ADTs and generic programming.
...
@@ -243,10 +244,10 @@ This paper is also about ADTs and generic programming.
%
%
More specifically, we show how to exploit the notion of extensional
More specifically, we show how to exploit the notion of extensional
equality preservation to inform the design of ADTs for generic
equality preservation to inform the design of ADTs for generic
programming and embedded domain-specific languages (DSL).
programming and embedded domain-specific languages (DSL
s
).
%
%
This is exemplified in sections \ref{section:functors} and
This is exemplified in sections \ref{section:functors} and
\ref{section:monads}
for
ADTs for functors and monads but we conjecture
\ref{section:monads}
with
ADTs for functors and monads but we conjecture
that other abstract data types, e.g. for applicatives and arrows, could
that other abstract data types, e.g. for applicatives and arrows, could
also profit from a design informed by the notion of preservation of
also profit from a design informed by the notion of preservation of
extensional equality.
extensional equality.
...
@@ -285,8 +286,8 @@ of important research for the last thirty years.
...
@@ -285,8 +286,8 @@ of important research for the last thirty years.
Since Hofmann's seminal work \citep{hofmann1995extensional}, setoids
Since Hofmann's seminal work \citep{hofmann1995extensional}, setoids
have been the established, but also often dreaded (who coined the
have been the established, but also often dreaded (who coined the
expression \emph{``setoid hell''}?) means to deal with extensional
expression \emph{``setoid hell''}?) means to deal with extensional
concepts in intensional type theory
,
see also section
concepts in intensional type theory
(
see also section
\ref{section:relatedwork}.
\ref{section:relatedwork}
)
.
%
%
Eventually, the study of Martin-Löf's equality type has lead to the
Eventually, the study of Martin-Löf's equality type has lead to the
development of Homotopy Type Theory and Voevodsky's Univalent
development of Homotopy Type Theory and Voevodsky's Univalent
...
@@ -326,11 +327,11 @@ These can be type-checked with Idris 1.3.2 and are available at
...
@@ -326,11 +327,11 @@ These can be type-checked with Idris 1.3.2 and are available at
%, see \texttt{README.md} in the paper's folder.
%, see \texttt{README.md} in the paper's folder.
%
%
In the next section we present a motivating example from monadic
%
In the next section we present a motivating example from monadic
dynamical systems, in section~\ref{section:functors} we explore
%
dynamical systems, in section~\ref{section:functors} we explore
extensional equality preservation for functors and in section
%
extensional equality preservation for functors and in section
\ref{section:monads} for monads.
%
\ref{section:monads} for monads.
%
%
%
We continue with dynamical systems applications in section~\ref{section:applications}
%
We continue with dynamical systems applications in section~\ref{section:applications}
and finish with related work (section~\ref{section:relatedwork}) and
%
and finish with related work (section~\ref{section:relatedwork}) and
conclusions (section~\ref{section:conclusions}).
%
conclusions (section~\ref{section:conclusions}).
2020.Extensional equality preservation and verified generic programming/Applications.lidr
View file @
b4e5227f
...
@@ -141,6 +141,7 @@ As for |flowLemma2|, proving the representation lemma is straightforward
...
@@ -141,6 +141,7 @@ As for |flowLemma2|, proving the representation lemma is straightforward
but crucially relies on associativity of Kleisli composition and thus, as
but crucially relies on associativity of Kleisli composition and thus, as
seen in section \ref{section:monads}, on preservation of extensional
seen in section \ref{section:monads}, on preservation of extensional
equality:
equality:
\pagebreak
% > reprLemma f Z mx =
% > reprLemma f Z mx =
% > ( (repr (flow f Z)) mx ) ={ Refl }=
% > ( (repr (flow f Z)) mx ) ={ Refl }=
...
@@ -150,7 +151,7 @@ equality:
...
@@ -150,7 +151,7 @@ equality:
% > ( flowDet (repr f) Z mx ) QED
% > ( flowDet (repr f) Z mx ) QED
> reprLemma f Z mx = Fat.pureRightIdKleisli id mx
> reprLemma f Z mx = Fat.pureRightIdKleisli id mx
>
> reprLemma f (S m) mx =
> reprLemma f (S m) mx =
> ( repr (flow f (S m)) mx ) ={ Refl }=
> ( repr (flow f (S m)) mx ) ={ Refl }=
> ( (id >=> flow f (S m)) mx ) ={ Refl }=
> ( (id >=> flow f (S m)) mx ) ={ Refl }=
...
@@ -166,11 +167,11 @@ Notice also the application of |kleisliLeapfrog| to deduce |(id >=>
...
@@ -166,11 +167,11 @@ Notice also the application of |kleisliLeapfrog| to deduce |(id >=>
flow f m) ((id >=> f) mx)| from |((id >=> f) >=> flow f m) mx|.
flow f m) ((id >=> f) mx)| from |((id >=> f) >=> flow f m) mx|.
%
%
If we had formulated the theory in terms of bind instead of Kleisli
If we had formulated the theory in terms of bind instead of Kleisli
composition, the two expressions would
be
intensionally equal.
composition, the two expressions would
have been
intensionally equal.
\paragraph*{Flows and trajectories.}
\paragraph*{Flows and trajectories.}
%
%
The
last application of preservation of extensional
Our
last application of preservation of extensional
equality in the context of dynamical systems theory is a result about
equality in the context of dynamical systems theory is a result about
flows and trajectories.
flows and trajectories.
%
%
...
@@ -188,7 +189,7 @@ is an |M|-structure containing just |[x]|.
...
@@ -188,7 +189,7 @@ is an |M|-structure containing just |[x]|.
To compute the trajectories for |S n| steps, we first bind the outcome
To compute the trajectories for |S n| steps, we first bind the outcome
of a single step |f x : M X| into |trj f n|.
of a single step |f x : M X| into |trj f n|.
%
%
This results in an |M|-structure of vectors of length |
S
n|.
This results in an |M|-structure of vectors of length |n|.
%
%
Finally, we prepend these possible trajectories with the initial state
Finally, we prepend these possible trajectories with the initial state
|x|.
|x|.
...
@@ -284,4 +285,4 @@ induction.
...
@@ -284,4 +285,4 @@ induction.
%
%
As in the |flowTrjLemma| discussed above, |map| preserving extensional
As in the |flowTrjLemma| discussed above, |map| preserving extensional
equality turns out to be pivotal in applying the induction hypothesis,
equality turns out to be pivotal in applying the induction hypothesis,
see \cite
p
{brede2020} for details.
see \cite
t
{brede2020} for details.
2020.Extensional equality preservation and verified generic programming/Conclusions.lidr
View file @
b4e5227f
...
@@ -12,7 +12,7 @@
...
@@ -12,7 +12,7 @@
\label{section:conclusions}
\label{section:conclusions}
In dependently typed programming in the context of Martin-Löf type
In dependently typed programming in the context of Martin-Löf type
theories \citep{nordstrom1990programming
, martinlof1984
}, the problem of
theories \citep{
martinlof1984,
nordstrom1990programming}, the problem of
how to specify abstract data types for verified generic programming is
how to specify abstract data types for verified generic programming is
still not well understood.
still not well understood.
%
%
...
...
2020.Extensional equality preservation and verified generic programming/Example.lidr
View file @
b4e5227f
...
@@ -81,17 +81,16 @@ With |compPresIE| from section~\ref{section:about}, one can implement
...
@@ -81,17 +81,16 @@ With |compPresIE| from section~\ref{section:about}, one can implement
%
%
The base case is trivial
The base case is trivial
> flowLemma f
Z =
Refl
> flowLemma f
Z =
Refl
For readability, we spell out the proof sketch for the induction step in
For readability, we spell out the proof sketch for the induction step in
full:
full:
> flowLemma f ( S n) =
> flowLemma f ( S n) = ( flowL f (S n) ) ={ Refl }=
> ( flowL f (S n) ) ={ Refl }=
> ( flowL f n . f ) ={ compPresIE (flowLemma f n) Refl }=
> ( flowL f n . f ) ={ compPresIE (flowLemma f n) Refl }=
> ( flowR f n . f ) ={ flowRLemma f n }=
> ( flowR f n . f ) ={ flowRLemma f n }=
> ( f . flowR f n ) ={ Refl }=
> ( f . flowR f n ) ={ Refl }=
> ( flowR f (S n) ) QED
> ( flowR f (S n) ) QED
First, we apply the definition of |flowL| to deduce |flowL f (S n) =
First, we apply the definition of |flowL| to deduce |flowL f (S n) =
flowL f n . f|.
flowL f n . f|.
...
@@ -109,15 +108,22 @@ associativity and preservation of intensional equality again.
...
@@ -109,15 +108,22 @@ associativity and preservation of intensional equality again.
< flowRLemma : {X : Type} -> (f : X -> X) -> (n : Nat) -> flowR f n . f = f . flowR f n
< flowRLemma : {X : Type} -> (f : X -> X) -> (n : Nat) -> flowR f n . f = f . flowR f n
> flowRLemma f Z = Refl
> flowRLemma f Z = Refl
> flowRLemma f ( S n) =
> flowRLemma f ( S n) = ( flowR f (S n) . f ) ={ Refl }=
> ( flowR f (S n) . f ) ={ Refl }=
> ( (f . flowR f n) . f ) ={ compAssociative f (flowR f n) f }=
> ( (f . flowR f n) . f ) ={ compAssociative f (flowR f n) f }=
> ( f . (flowR f n . f) ) ={ compPresIE Refl (flowRLemma f n) }=
> ( f . (flowR f n . f) ) ={ compPresIE Refl (flowRLemma f n) }=
> ( f . (f . flowR f n) ) ={ Refl }=
> ( f . (f . flowR f n) ) ={ Refl }=
> ( f . flowR f (S n) ) QED
> ( f . flowR f (S n) ) QED
\end{joincode}
\end{joincode}
% > flowRLemma f Z = Refl
% > flowRLemma f ( S n) =
% > ( flowR f (S n) . f ) ={ Refl }=
% > ( (f . flowR f n) . f ) ={ compAssociative f (flowR f n) f }=
% > ( f . (flowR f n . f) ) ={ compPresIE Refl (flowRLemma f n) }=
% > ( f . (f . flowR f n) ) ={ Refl }=
% > ( f . flowR f (S n) ) QED
%
\noindent
\noindent
Let's summarize: we have considered the special case of deterministic
Let's summarize: we have considered the special case of deterministic
...
@@ -152,18 +158,15 @@ on a set |X| are functions of type |X -> M X| where |M| is a monad.
...
@@ -152,18 +158,15 @@ on a set |X| are functions of type |X -> M X| where |M| is a monad.
%
%
When |M| is the identity monad, one recovers the deterministic case.
When |M| is the identity monad, one recovers the deterministic case.
%
%
%%For |M| equal to |List| one has non-deterministic systems and |M| equal
%%to the finite probability distribution monads |Dist|
%%\citep{10.1017/S0956796805005721} or |SimpleProb|
%%\citep{2017_Botta_Jansson_Ionescu} formalizes the notion of stochastic
%%systems.
When |M| is |List| one has non-deterministic systems, and finite
When |M| is |List| one has non-deterministic systems, and finite
probability monads (e.g. |Dist| \citep{10.1017/S0956796805005721} or
probability monads
|SimpleProb| \citep{ionescu2009, 2017_Botta_Jansson_Ionescu}) capture the notion of
%*TODO: perhaps cite (e.g. |Dist| \citep{10.1017/S0956796805005721} or |SimpleProb| \citep{ionescu2009, 2017_Botta_Jansson_Ionescu})
stochastic systems.
capture the notion of stochastic systems.
%
\nocite{10.1017/S0956796805005721,ionescu2009, 2017_Botta_Jansson_Ionescu}
%
%
Other monads encode other notions of uncertainty, see
%
Other monads encode other notions of uncertainty, see
\citep{ionescu2009,giry1981}.
\cite
p
{ionescu2009,giry1981}
.
\
no
cite{ionescu2009,giry1981}
One can extend the flow (and, as we will see in
One can extend the flow (and, as we will see in
section~\ref{section:applications}, other elementary operations) of
section~\ref{section:applications}, other elementary operations) of
...
@@ -171,15 +174,15 @@ deterministic systems to the general, monadic case by replacing |id|
...
@@ -171,15 +174,15 @@ deterministic systems to the general, monadic case by replacing |id|
with |pure| and function composition with Kleisli composition (|>=>|):
with |pure| and function composition with Kleisli composition (|>=>|):
%PJ: The repeated type signature is a bit disturbing. Perhaps use |using|?
%PJ: The repeated type signature is a bit disturbing. Perhaps use |using|?
> flowMonL : {X : Type} -> {M : Type -> Type} -> Monad M =>
> flowMonL
: {X : Type} -> {M : Type -> Type} -> Monad M =>
> (X -> M X) -> Nat -> (X -> M X)
>
(X -> M X) -> Nat -> (X -> M X)
> flowMonL f Z = pure
> flowMonL
{-"\,"-}
f Z = pure
> flowMonL f ( S n) = flowMonL f n >=> f
> flowMonL
f ( S n) = flowMonL f n >=> f
>
>
> flowMonR : {X : Type} -> {M : Type -> Type} -> Monad M =>
> flowMonR
: {X : Type} -> {M : Type -> Type} -> Monad M =>
> (X -> M X) -> Nat -> (X -> M X)
>
(X -> M X) -> Nat -> (X -> M X)
> flowMonR f Z = pure
> flowMonR
f Z = pure
> flowMonR f ( S n) = f >=> flowMonR f n
> flowMonR
f ( S n) = f >=> flowMonR f n
Notice, however, that now the implementations of |flowMonL| and
Notice, however, that now the implementations of |flowMonL| and
|flowMonR| depend on |(>=>)|, which is a monad-specific operation.
|flowMonR| depend on |(>=>)|, which is a monad-specific operation.
...
@@ -193,11 +196,12 @@ What do we know about Kleisli composition \emph{in general}?
...
@@ -193,11 +196,12 @@ What do we know about Kleisli composition \emph{in general}?
%
%
We discuss this question in the next two sections but let us
We discuss this question in the next two sections but let us
anticipate that, if we require functors to preserve the extensional
anticipate that, if we require functors to preserve the extensional
equality of arrows (in addition to identity and composition)
equality of arrows (in addition to identity and composition) and
and Kleisli composition to fulfil the specification
Kleisli composition to fulfil the specification
%
\vspace*{-2ex}
\begin{center}
\begin{center}
\begin{tikzcd}[
row sep=large,
column sep=large]
\begin{tikzcd}[column sep=large]
|M C|
|M C|
& |M (M C)| \arrow[l, "|join|"]
& |M (M C)| \arrow[l, "|join|"]
& |M B| \arrow[l, "|map g|"]
& |M B| \arrow[l, "|map g|"]
...
@@ -210,20 +214,6 @@ and Kleisli composition to fulfil the specification
...
@@ -210,20 +214,6 @@ and Kleisli composition to fulfil the specification
> kleisliSpec : {A, B, C : Type} -> {M : Type -> Type} -> Monad M =>
> kleisliSpec : {A, B, C : Type} -> {M : Type -> Type} -> Monad M =>
> (f : A -> M B) -> (g : B -> M C) -> (f >=> g) <=> join . map g . f
> (f : A -> M B) -> (g : B -> M C) -> (f >=> g) <=> join . map g . f
% \begin{minipage}{0.4\textwidth}
% \begin{tikzcd}[row sep=large, column sep=large]
% |A| \arrow[r, "|f|"] \arrow[d, "|f>=>g|"] & |M B| \arrow[d, "|map g|"] \\
% |M C| & |M (M C)| \arrow[l, "|join|"]
% \end{tikzcd}
% \end{minipage}
%
% \begin{tikzcd}[row sep=large, column sep=large]
% |A| \arrow[r, "|f|"] \arrow[rrr, bend left=30, "|f>=>g|"]
% & |M B| \arrow[r, "|map g|"]
% & |M (M C)| \arrow[r, "|join|"]
% & |M C|
% \end{tikzcd}
%
then we can derive preservation of extensional equality
then we can derive preservation of extensional equality
> kleisliPresEE : {A, B, C : Type} -> {M : Type -> Type} -> Monad M =>
> kleisliPresEE : {A, B, C : Type} -> {M : Type -> Type} -> Monad M =>
...
@@ -240,8 +230,8 @@ From these premises, we can prove the \emph{extensional} equality of
...
@@ -240,8 +230,8 @@ From these premises, we can prove the \emph{extensional} equality of
|flowMonL| and |flowMonR| using a similar lemma as in the deterministic case:
|flowMonL| and |flowMonR| using a similar lemma as in the deterministic case:
%
%
> flowMonRLem
ma
: {X : Type} -> {M : Type -> Type} -> Monad M =>
> flowMonRLem : {X : Type} -> {M : Type -> Type} -> Monad M =>
>
(f : X -> M X) -> (n : Nat) -> (flowMonR f n >=> f) <=> (f >=> flowMonR f n)
> (f : X -> M X) -> (n : Nat) -> (flowMonR f n >=> f) <=> (f >=> flowMonR f n)
First, notice that the base case of the lemma requires computing
First, notice that the base case of the lemma requires computing
evidence that |pure >=> f| is extensionally equal to |f >=> pure|.
evidence that |pure >=> f| is extensionally equal to |f >=> pure|.
...
@@ -262,7 +252,7 @@ Kleisli composition: for |f : A -> M B| we have
...
@@ -262,7 +252,7 @@ Kleisli composition: for |f : A -> M B| we have
%endif
%endif
> flowMonRLem
ma
f Z x =
> flowMonRLem f Z x =
> ( (flowMonR f Z >=> f) x ) ={ Refl }=
> ( (flowMonR f Z >=> f) x ) ={ Refl }=
> ( (pure >=> f) x ) ={ pureLeftIdKleisli f x }=
> ( (pure >=> f) x ) ={ pureLeftIdKleisli f x }=
> ( f x ) ={ sym (pureRightIdKleisli f x) }=
> ( f x ) ={ sym (pureRightIdKleisli f x) }=
...
@@ -273,15 +263,15 @@ As we will see in subsection \ref{def:pureLeftIdKleisli},
...
@@ -273,15 +263,15 @@ As we will see in subsection \ref{def:pureLeftIdKleisli},
|pureLeftIdKleisli| and |pureRightIdKleisli| are either ADT axioms or
|pureLeftIdKleisli| and |pureRightIdKleisli| are either ADT axioms or
theorems, depending of the formulation of the monad ADT.
theorems, depending of the formulation of the monad ADT.
%
%
The induction step of |flowMonRLem
ma
| relies on preservation of
The induction step of |flowMonRLem| relies on preservation of
extensional equality and on associativity of Kleisli composition:
extensional equality and on associativity of Kleisli composition:
> flowMonRLem
ma
f ( S n) x =
> flowMonRLem f ( S n) x =
> let rest = flowMonR f n in
> let rest = flowMonR f n in
> ( (flowMonR f (S n) >=> f) x ) ={ Refl }=
> ( (flowMonR f (S n) >=> f) x ) ={ Refl }=
> ( ((f >=> rest) >=> f) x ) ={ kleisliAssoc f rest f x }=
> ( ((f >=> rest) >=> f) x ) ={ kleisliAssoc f rest f x }=
> ( (f >=> (rest >=> f)) x ) ={ kleisliPresEE f f (rest >=> f) (f >=> rest)
> ( (f >=> (rest >=> f)) x ) ={ kleisliPresEE f f (rest >=> f) (f >=> rest)
> (\ v => Refl) (flowMonRLem
ma
f n) x }=
> (\ v => Refl) (flowMonRLem f n) x }=
> ( (f >=> (f >=> rest)) x ) ={ Refl }=
> ( (f >=> (f >=> rest)) x ) ={ Refl }=
> ( (f >=> flowMonR f (S n)) x ) QED
> ( (f >=> flowMonR f (S n)) x ) QED
...
@@ -293,16 +283,16 @@ Finally, the extensional equality of |flowMonL| and |flowMonR|
...
@@ -293,16 +283,16 @@ Finally, the extensional equality of |flowMonL| and |flowMonR|
> flowMonLemma f Z x = Refl
> flowMonLemma f Z x = Refl
>
>
> flowMonLemma f (S n) x =
> flowMonLemma f (S n) x =
> let fLn = flowMonL f n
> let fLn
= flowMonL
f n
> fRn = flowMonR f n in
> fRn
= flowMonR
f n
in
> ( flowMonL f (S n) x ) ={ Refl }=
> ( flowMonL f (S n) x ) ={ Refl }=
> ( (fLn >=> f) x ) ={ kleisliPresEE fLn fRn f f
> ( (fLn >=> f) x ) ={ kleisliPresEE fLn fRn f f
> (flowMonLemma f n) (\v => Refl) x }=
> (flowMonLemma f n) (\v => Refl) x }=
> ( (fRn >=> f) x ) ={ flowMonRLem
ma
f n x }=
> ( (fRn >=> f) x ) ={ flowMonRLem f n x }=
> ( (f >=> fRn) x ) ={ Refl }=
> ( (f >=> fRn) x ) ={ Refl }=
> ( flowMonR f (S n) x ) QED
> ( flowMonR f (S n) x ) QED
follows from |flowMonRLem
ma
| and, again, preservation of extensional equality.
follows from |flowMonRLem| and, again, preservation of extensional equality.
\paragraph*{Discussion.} Before we turn to the next section, let us discuss one
\paragraph*{Discussion.} Before we turn to the next section, let us discuss one
objection to what we have just done.
objection to what we have just done.
...
@@ -326,8 +316,9 @@ these would make our monad interface impossible (or at least very
...
@@ -326,8 +316,9 @@ these would make our monad interface impossible (or at least very
hard) to implement.
hard) to implement.
%
%
In general, we cannot rely on |f >=> g| to be intensionally equal to
In general, we cannot rely on |f >=> g| to be intensionally equal to
|join . map g . f| (or, for that matter, to be intensionally equal to
|join . map g . f|.
|\a => f a >>= g|).
% we haven't introduced bind yet...
%(or, for that matter, to be intensionally equal to |\a => f a >>= g|).
In designing ADTs and formulating generic results, we have to be careful
In designing ADTs and formulating generic results, we have to be careful
not to impose too strong proof obligations on implementors.
not to impose too strong proof obligations on implementors.
...
...
2020.Extensional equality preservation and verified generic programming/Functors.lidr
View file @
b4e5227f
...
@@ -32,7 +32,7 @@ $\mathcal{D}$ (often both denoted by |F|) such that for each arrow |f
...
@@ -32,7 +32,7 @@ $\mathcal{D}$ (often both denoted by |F|) such that for each arrow |f
: A -> B| in $\mathcal{C}$ there is an arrow |F f : F A -> F B| in
: A -> B| in $\mathcal{C}$ there is an arrow |F f : F A -> F B| in
$\mathcal{D}$.
$\mathcal{D}$.
%
%
For an introduction to category theory, see \cite
p
{pierce_basic_1991}.
For an introduction to category theory, see \cite
t
{pierce_basic_1991}.
%
%
The arrow map preserves identity arrows and arrow composition.
The arrow map preserves identity arrows and arrow composition.
%
%
...
@@ -172,26 +172,24 @@ proof looks as follows:
...
@@ -172,26 +172,24 @@ proof looks as follows:
% {-" below=\the\belowdisplayskip"-}
% {-" below=\the\belowdisplayskip"-}
> mapListPresEE : {A, B : Type} -> (f, g : A -> B) -> f <=> g -> mapList f <=> mapList g
> mapListPresEE : {A, B : Type} -> (f, g : A -> B) -> f <=> g -> mapList f <=> mapList g
> mapListPresEE f g fEEg []
=
Refl
> mapListPresEE f g fEEg []
=
Refl
> mapListPresEE f g fEEg (a :: as)
=
> mapListPresEE f g fEEg (a :: as)
= {-"\,"-}
> ( mapList f (a :: as) ) ={ Refl }=
> ( mapList f (a :: as) )
={
Refl }=
> ( f a :: mapList f as ) ={ cong {f = (::{-"~"-} mapList f as)} (fEEg a) }=
> ( f a :: mapList f as )
={
cong {f = (::{-"~"-} mapList f as)} (fEEg a) }=
> ( g a :: mapList f as ) ={ cong (mapListPresEE f g fEEg as) }=
> ( g a :: mapList f as )
={
cong (mapListPresEE f g fEEg as) }=
> ( g a :: mapList g as ) ={ Refl }=
> ( g a :: mapList g as )
={
Refl }=
> ( mapList g (a :: as) ) QED
> ( mapList g (a :: as) )
QED
In general the proofs have a very simple structure: they use the |f
In general the proofs have a very simple structure: they use the |f
<=> g| arguments to transform the arguments of type |A| expected by
<=> g| arguments at the ``leaves'', and otherwise only use the
the constructors into arguments of type |B|, and otherwise only use
induction hypotheses.
the induction hypotheses.
%
%
They can also be written as dependent folds, but this results in less
%
They can also be written as dependent folds, but this results in less
readable proofs.
%
readable proofs.
%
%
(
With a suitable universe of codes for types, or a library for
With a suitable universe of codes for types, or a library for
parametricity proofs, these proofs can be automated using
parametricity proofs, these proofs can be automated using
datatype-generic programming.)
datatype-generic programming.
%
%if False
%if False
We can write |mapListPresEE| in a more condensed form using Idris'
We can write |mapListPresEE| in a more condensed form using Idris'
...
@@ -240,13 +238,13 @@ This is a common pattern for proofs of |mapPresEE|.
...
@@ -240,13 +238,13 @@ This is a common pattern for proofs of |mapPresEE|.
%endif
%endif
Let's now turn to a type constructor that is not an instance of
Let's now turn to a type constructor that is not an instance of
|VeriFunctor|, namely |Reader E| for some environment |E : Type|.
our
|VeriFunctor|, namely |Reader E| for some environment |E : Type|.
> Reader : Type -> Type -> Type
> Reader : Type -> Type -> Type
> Reader E A = E -> A
> Reader E A = E -> A
>
>
> mapR
eader
: {A, B, E : Type} -> (A -> B) -> Reader E A -> Reader E B
> mapR : {A, B, E : Type} -> (A -> B) ->
(
Reader E A -> Reader E B
)
> mapR
eader
f r = f . r
> mapR f r = f . r
If we try to implement preservation of extensional equality we end up with
If we try to implement preservation of extensional equality we end up with
...
@@ -258,18 +256,17 @@ If we try to implement preservation of extensional equality we end up with
...
@@ -258,18 +256,17 @@ If we try to implement preservation of extensional equality we end up with
%endif
%endif
> mapReaderPresEE : {A, B : Type} -> (f, g : A -> B) ->
> mapRPresEE : {A, B : Type} -> (f, g : A -> B) -> f <=> g -> mapR f <=> mapR g
> f <=> g -> mapReader f <=> mapReader g
> mapRPresEE f g fEEg r =
> mapReaderPresEE f g fEEg r =
> ( mapR f r) ={ Refl }=
> ( mapReader f r) ={ Refl }=
> ( f . r ) ={ whatnow1 r }= -- here we need |f = g| to proceed
> ( f . r ) ={ whatnow1 r }= -- here we need |f = g| to proceed
> ( g . r ) ={ Refl }=
> ( g . r ) ={ Refl }=
> ( mapR
eader
g r) QED
> ( mapR g r)
QED
Notice the question mark in front of |whatnow1r|. This introduces an
Notice the question mark in front of |whatnow1r|. This introduces an
unresolved proof step and allows us to ask Idris to help us implementing
unresolved proof step and allows us to ask Idris to help us implementing
this step, see ``Elaborator Reflection -- Holes'' in \citep{idrisdocs}.
this step, see ``Elaborator Reflection -- Holes'' in \citep{idrisdocs}.
Among others, we can ask about the
Among other
thing
s, we can ask about the
type of |whatnow1r|. Perhaps not surprisingly, this turns out to be |f
type of |whatnow1r|. Perhaps not surprisingly, this turns out to be |f
. r = g . r|.
. r = g . r|.
...
@@ -278,9 +275,6 @@ all |e : E|, we cannot deduce |f . r = g . r| without extensionality.
...
@@ -278,9 +275,6 @@ all |e : E|, we cannot deduce |f . r = g . r| without extensionality.
%
%
Thus |Reader E| does not implement the |VeriFunctor| interface, but it
Thus |Reader E| does not implement the |VeriFunctor| interface, but it
is ``very close''.
is ``very close''.
%
\footnote{By a similar argument, |mapPresEE| does not hold for the
continuation monad.}
%if False
%if False
> (<==>) : {A, B, C : Type} -> (f, g : A -> B -> C) -> Type
> (<==>) : {A, B, C : Type} -> (f, g : A -> B -> C) -> Type
...
@@ -290,13 +284,16 @@ is ``very close''.
...
@@ -290,13 +284,16 @@ is ``very close''.