Discussion:
[Agda] Standard WellFounded
Sergei Meshveliani
2018-08-07 17:51:30 UTC
Permalink
Dear all,

I am trying to understand how to use WellFounded of Standard library.

Can anybody demonstrate it on the following example?

--------------------------------------------------------------
open import Function using (_∘_)
open import Data.List using (List; []; _∷_)
open import Data.Bin using (Bin; toBits; pred)

open Bin

predBin : Bin → Bin
predBin = pred ∘ toBits

downFrom : Bin → List Bin -- x ∷ x-1 ∷ x-2 ∷ ... ∷ 0# ∷ []
downFrom 0# = 0# ∷ []
downFrom (bs 1#) = (bs 1#) ∷ (downFrom (predBin (bs 1#)))
--------------------------------------------------------------

downFrom is not recognized as terminating.
How to reorganize it with using items from
Induction/*, WellFounded.agda ?

Thanks,

------
Sergei
Sergei Meshveliani
2018-08-08 10:13:13 UTC
Permalink
Post by Sergei Meshveliani
Dear all,
I am trying to understand how to use WellFounded of Standard library.
Can anybody demonstrate it on the following example?
--------------------------------------------------------------
open import Function using (_∘_)
open import Data.List using (List; []; _∷_)
open import Data.Bin using (Bin; toBits; pred)
open Bin
predBin : Bin → Bin
predBin = pred ∘ toBits
downFrom : Bin → List Bin -- x ∷ x-1 ∷ x-2 ∷ ... ∷ 0# ∷ []
downFrom 0# = 0# ∷ []
downFrom (bs 1#) = (bs 1#) ∷ (downFrom (predBin (bs 1#)))
--------------------------------------------------------------
downFrom is not recognized as terminating.
How to reorganize it with using items from
Induction/*, WellFounded.agda ?
I presumed also that it is already given the property

postulate
predBin-< : (bs : List Bit) -> predBin (bs 1#) < (bs 1#)

(I do not mean to deal here with its proof).

--
SM
Sandro Stucki
2018-08-08 15:49:50 UTC
Permalink
Post by Sergei Meshveliani
Can anybody demonstrate it on the following example?
Here you go:

--------------------------------------------------------------
open import Function using (_∘_; _on_)
open import Data.List using (List; []; _∷_)
open import Data.Bin using (Bin; toBits; pred; _<_; less; toℕ)
open import Data.Digit using (Bit)
import Data.Nat as Nat
import Induction.Nat as NatInd
open import Induction.WellFounded

open Bin

predBin : Bin → Bin
predBin = pred ∘ toBits

postulate
predBin-< : (bs : List Bit) -> predBin (bs 1#) < (bs 1#)

-- The strict order on binary naturals implies the strict order on the
-- corresponding unary naturals.
<⇒<ℕ : ∀ {b₁ b₂} → b₁ < b₂ → (Nat._<_ on toℕ) b₁ b₂
<⇒<ℕ (less lt) = lt

-- We can derive well-foundedness of _<_ on binary naturals from
-- well-foundedness of _<_ on unary naturals.
<-wellFounded : WellFounded _<_
<-wellFounded =
Subrelation.wellFounded <⇒<ℕ (Inverse-image.wellFounded toℕ
NatInd.<-wellFounded)

open All <-wellFounded using () renaming (wfRec to <-rec)

downFrom : Bin → List Bin -- x ∷ x-1 ∷ x-2 ∷ ... ∷ 0# ∷ []
downFrom = <-rec _ _ df
where
df : (b : Bin) → (∀ b′ → b′ < b → List Bin) → List Bin
df 0# dfRec = 0# ∷ []
df (bs 1#) dfRec = (bs 1#) ∷ (dfRec (predBin (bs 1#)) (predBin-< bs))
--------------------------------------------------------------

In order to use well-founded induction, we first have to prove that
the strict order < is indeed well-founded. Thankfully, the standard
library already contains such a proof for the strict order on (unary)
naturals as well as a collection of combinators for deriving
well-foundedness of relations from others (in this case the strict
order on unary naturals).

The core of the implementation of `downFrom' via well-founded
recursion is the function `df', which has the same signature as
`downFrom' except for the additional argument `dfRec', which serves as
the 'induction hypothesis'. The argument `dfRec' is itself a function
with (almost) the same signature as `downFrom' allowing us to make
recursive calls (i.e. take a recursive step), provided we can prove
that the first argument of the recursive call (i.e. the argument to
the induction hypothesis) is smaller than the first argument of the
enclosing call to `df'. The proof that this is indeed the case is
passed to `dfRec' as an additional argument of type b′ < b.

The following answer on Stackoverflow contains a nice explanation on
how all of this is implemented in Agda under the hood:
https://stackoverflow.com/a/19667260

Cheers
/Sandro
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Dear all,
I am trying to understand how to use WellFounded of Standard library.
Can anybody demonstrate it on the following example?
--------------------------------------------------------------
open import Function using (_∘_)
open import Data.List using (List; []; _∷_)
open import Data.Bin using (Bin; toBits; pred)
open Bin
predBin : Bin → Bin
predBin = pred ∘ toBits
downFrom : Bin → List Bin -- x ∷ x-1 ∷ x-2 ∷ ... ∷ 0# ∷ []
downFrom 0# = 0# ∷ []
downFrom (bs 1#) = (bs 1#) ∷ (downFrom (predBin (bs 1#)))
--------------------------------------------------------------
downFrom is not recognized as terminating.
How to reorganize it with using items from
Induction/*, WellFounded.agda ?
I presumed also that it is already given the property
postulate
predBin-< : (bs : List Bit) -> predBin (bs 1#) < (bs 1#)
(I do not mean to deal here with its proof).
--
SM
_______________________________________________
Agda mailing list
https://lists.chalmers.se/mailman/listinfo/agda
Sergei Meshveliani
2018-08-08 18:33:06 UTC
Permalink
(I have forgotten to copy my reply to the list)

Sandro, thank you very much.
I do understand a certain part of this. And downFrom is type-checked.

Then I try to mimic the approach to the function divMod for Bin
(without understanding the type of <-rec):

--------------------------------------------------
record DivMod (dividend divisor : Bin) : Set where
constructor result
field
quotient : Bin
remainder : Bin
equality : dividend ≡ remainder + quotient * divisor
rem<divisor : remainder < divisor

divMod : (a b : Bin) → b ≢ 0# → DivMod a b
divMod a b b≢0 =
<-rec _ _ aux
where
postulate
aux : (a : Bin) → (∀ x → x < a → DivMod x b) → DivMod a b
---------------------------------------------------


Agda 2.5.4 reports

(x : Bin) → DivMod x b !=< DivMod a b of type Set
when checking that the expression <-rec _ _ aux has type DivMod a b

Can you, please, tell: how to fix?

May be one needs to understand the type of All.wfRec.
But there it is written something brain-twisting, and it refers the
Recursor. I searched by `grep', but Recursor is not visible at all
in /Induction directory, I do not see where it is imported from.

Thanks,

------
Sergei
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Can anybody demonstrate it on the following example?
--------------------------------------------------------------
open import Function using (_∘_; _on_)
open import Data.List using (List; []; _∷_)
open import Data.Bin using (Bin; toBits; pred; _<_; less; toℕ)
open import Data.Digit using (Bit)
import Data.Nat as Nat
import Induction.Nat as NatInd
open import Induction.WellFounded
open Bin
predBin : Bin → Bin
predBin = pred ∘ toBits
postulate
predBin-< : (bs : List Bit) -> predBin (bs 1#) < (bs 1#)
-- The strict order on binary naturals implies the strict order on the
-- corresponding unary naturals.
<⇒<ℕ : ∀ {b₁ b₂} → b₁ < b₂ → (Nat._<_ on toℕ) b₁ b₂
<⇒<ℕ (less lt) = lt
-- We can derive well-foundedness of _<_ on binary naturals from
-- well-foundedness of _<_ on unary naturals.
<-wellFounded : WellFounded _<_
<-wellFounded =
Subrelation.wellFounded <⇒<ℕ (Inverse-image.wellFounded toℕ
NatInd.<-wellFounded)
open All <-wellFounded using () renaming (wfRec to <-rec)
downFrom : Bin → List Bin -- x ∷ x-1 ∷ x-2 ∷ ... ∷ 0# ∷ []
downFrom = <-rec _ _ df
where
df : (b : Bin) → (∀ b′ → b′ < b → List Bin) → List Bin
df 0# dfRec = 0# ∷ []
df (bs 1#) dfRec = (bs 1#) ∷ (dfRec (predBin (bs 1#)) (predBin-< bs))
--------------------------------------------------------------
In order to use well-founded induction, we first have to prove that
the strict order < is indeed well-founded. Thankfully, the standard
library already contains such a proof for the strict order on (unary)
naturals as well as a collection of combinators for deriving
well-foundedness of relations from others (in this case the strict
order on unary naturals).
The core of the implementation of `downFrom' via well-founded
recursion is the function `df', which has the same signature as
`downFrom' except for the additional argument `dfRec', which serves as
the 'induction hypothesis'. The argument `dfRec' is itself a function
with (almost) the same signature as `downFrom' allowing us to make
recursive calls (i.e. take a recursive step), provided we can prove
that the first argument of the recursive call (i.e. the argument to
the induction hypothesis) is smaller than the first argument of the
enclosing call to `df'. The proof that this is indeed the case is
passed to `dfRec' as an additional argument of type b′ < b.
The following answer on Stackoverflow contains a nice explanation on
https://stackoverflow.com/a/19667260
Cheers
/Sandro
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Dear all,
I am trying to understand how to use WellFounded of Standard library.
Can anybody demonstrate it on the following example?
--------------------------------------------------------------
open import Function using (_∘_)
open import Data.List using (List; []; _∷_)
open import Data.Bin using (Bin; toBits; pred)
open Bin
predBin : Bin → Bin
predBin = pred ∘ toBits
downFrom : Bin → List Bin -- x ∷ x-1 ∷ x-2 ∷ ... ∷ 0# ∷ []
downFrom 0# = 0# ∷ []
downFrom (bs 1#) = (bs 1#) ∷ (downFrom (predBin (bs 1#)))
--------------------------------------------------------------
downFrom is not recognized as terminating.
How to reorganize it with using items from
Induction/*, WellFounded.agda ?
I presumed also that it is already given the property
postulate
predBin-< : (bs : List Bit) -> predBin (bs 1#) < (bs 1#)
(I do not mean to deal here with its proof).
--
SM
_______________________________________________
Agda mailing list
https://lists.chalmers.se/mailman/listinfo/agda
Sergei Meshveliani
2018-08-08 20:03:07 UTC
Permalink
Post by Sergei Meshveliani
(I have forgotten to copy my reply to the list)
Sandro, thank you very much.
I do understand a certain part of this. And downFrom is type-checked.
Then I try to mimic the approach to the function divMod for Bin
--------------------------------------------------
record DivMod (dividend divisor : Bin) : Set where
constructor result
field
quotient : Bin
remainder : Bin
equality : dividend ≡ remainder + quotient * divisor
rem<divisor : remainder < divisor
divMod : (a b : Bin) → b ≢ 0# → DivMod a b
divMod a b b≢0 =
<-rec _ _ aux
where
postulate
aux : (a : Bin) → (∀ x → x < a → DivMod x b) → DivMod a b
---------------------------------------------------
Agda 2.5.4 reports
(x : Bin) → DivMod x b !=< DivMod a b of type Set
when checking that the expression <-rec _ _ aux has type DivMod a b
Can you, please, tell: how to fix?
May be one needs to understand the type of All.wfRec.
But there it is written something brain-twisting, and it refers the
Recursor. I searched by `grep', but Recursor is not visible at all
in /Induction directory, I do not see where it is imported from.
I find now that this version is type-checked:

divMod a b b≢0# = aux a
where
aux : (a : Bin) → DivMod a b
aux = <-rec _ _ aux0
where
postulate
aux0 : (a : Bin) → (∀ x → x < a → DivMod x b) → DivMod a b

That is I reduce it explicitly to a function of a single argument.
I shall try further.


Thanks again,

------
Sergei
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Can anybody demonstrate it on the following example?
--------------------------------------------------------------
open import Function using (_∘_; _on_)
open import Data.List using (List; []; _∷_)
open import Data.Bin using (Bin; toBits; pred; _<_; less; toℕ)
open import Data.Digit using (Bit)
import Data.Nat as Nat
import Induction.Nat as NatInd
open import Induction.WellFounded
open Bin
predBin : Bin → Bin
predBin = pred ∘ toBits
postulate
predBin-< : (bs : List Bit) -> predBin (bs 1#) < (bs 1#)
-- The strict order on binary naturals implies the strict order on the
-- corresponding unary naturals.
<⇒<ℕ : ∀ {b₁ b₂} → b₁ < b₂ → (Nat._<_ on toℕ) b₁ b₂
<⇒<ℕ (less lt) = lt
-- We can derive well-foundedness of _<_ on binary naturals from
-- well-foundedness of _<_ on unary naturals.
<-wellFounded : WellFounded _<_
<-wellFounded =
Subrelation.wellFounded <⇒<ℕ (Inverse-image.wellFounded toℕ
NatInd.<-wellFounded)
open All <-wellFounded using () renaming (wfRec to <-rec)
downFrom : Bin → List Bin -- x ∷ x-1 ∷ x-2 ∷ ... ∷ 0# ∷ []
downFrom = <-rec _ _ df
where
df : (b : Bin) → (∀ b′ → b′ < b → List Bin) → List Bin
df 0# dfRec = 0# ∷ []
df (bs 1#) dfRec = (bs 1#) ∷ (dfRec (predBin (bs 1#)) (predBin-< bs))
--------------------------------------------------------------
In order to use well-founded induction, we first have to prove that
the strict order < is indeed well-founded. Thankfully, the standard
library already contains such a proof for the strict order on (unary)
naturals as well as a collection of combinators for deriving
well-foundedness of relations from others (in this case the strict
order on unary naturals).
The core of the implementation of `downFrom' via well-founded
recursion is the function `df', which has the same signature as
`downFrom' except for the additional argument `dfRec', which serves as
the 'induction hypothesis'. The argument `dfRec' is itself a function
with (almost) the same signature as `downFrom' allowing us to make
recursive calls (i.e. take a recursive step), provided we can prove
that the first argument of the recursive call (i.e. the argument to
the induction hypothesis) is smaller than the first argument of the
enclosing call to `df'. The proof that this is indeed the case is
passed to `dfRec' as an additional argument of type b′ < b.
The following answer on Stackoverflow contains a nice explanation on
https://stackoverflow.com/a/19667260
Cheers
/Sandro
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Dear all,
I am trying to understand how to use WellFounded of Standard library.
Can anybody demonstrate it on the following example?
--------------------------------------------------------------
open import Function using (_∘_)
open import Data.List using (List; []; _∷_)
open import Data.Bin using (Bin; toBits; pred)
open Bin
predBin : Bin → Bin
predBin = pred ∘ toBits
downFrom : Bin → List Bin -- x ∷ x-1 ∷ x-2 ∷ ... ∷ 0# ∷ []
downFrom 0# = 0# ∷ []
downFrom (bs 1#) = (bs 1#) ∷ (downFrom (predBin (bs 1#)))
--------------------------------------------------------------
downFrom is not recognized as terminating.
How to reorganize it with using items from
Induction/*, WellFounded.agda ?
I presumed also that it is already given the property
postulate
predBin-< : (bs : List Bit) -> predBin (bs 1#) < (bs 1#)
(I do not mean to deal here with its proof).
--
SM
_______________________________________________
Agda mailing list
https://lists.chalmers.se/mailman/listinfo/agda
_______________________________________________
Agda mailing list
https://lists.chalmers.se/mailman/listinfo/agda
Sergei Meshveliani
2018-08-09 19:40:27 UTC
Permalink
Thank you.
After this sample of downFrom I was able to program divMod for Bin.
But I am stuck with gcd for Bin.
Consider a contrived simple version:

------------------------------------------------------
postulate
rem : Bin → (y : Bin) → y ≢ 0# → Bin -- remainder of x by y.

rem< : (x y : Bin) → (y≢0 : y ≢ 0#) → rem x y y≢0 < y

gcd : Bin → Bin → Bin
gcd x y
with y ≟ 0#
... | yes _ = x
... | no y≢0 = gcd y (rem x y y≢0)

This lacks termination proof.
The argument pair (x , y) is replaced in recursion with (y , r),
where r < y. So, it is needed well-founded recursion:

gcd' : Bin → Bin → Bin
gcd' = <-rec _ _ gc
where
postulate
gc : Bin → (b : Bin) → (∀ x y → y < b → Bin) → Bin -- ??


I do not guess what signature to set for gc.
I set a hole "?" for gc, and the type checker shows

Induction.WellFounded.WfRec _<_ (λ _ → Bin → Bin)
.Relation.Unary._.⊆′ (λ _ → Bin → Bin)
-- ?

Can anybody help, please?

Thanks,

------
Sergei
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Can anybody demonstrate it on the following example?
--------------------------------------------------------------
open import Function using (_∘_; _on_)
open import Data.List using (List; []; _∷_)
open import Data.Bin using (Bin; toBits; pred; _<_; less; toℕ)
open import Data.Digit using (Bit)
import Data.Nat as Nat
import Induction.Nat as NatInd
open import Induction.WellFounded
open Bin
predBin : Bin → Bin
predBin = pred ∘ toBits
postulate
predBin-< : (bs : List Bit) -> predBin (bs 1#) < (bs 1#)
-- The strict order on binary naturals implies the strict order on the
-- corresponding unary naturals.
<⇒<ℕ : ∀ {b₁ b₂} → b₁ < b₂ → (Nat._<_ on toℕ) b₁ b₂
<⇒<ℕ (less lt) = lt
-- We can derive well-foundedness of _<_ on binary naturals from
-- well-foundedness of _<_ on unary naturals.
<-wellFounded : WellFounded _<_
<-wellFounded =
Subrelation.wellFounded <⇒<ℕ (Inverse-image.wellFounded toℕ
NatInd.<-wellFounded)
open All <-wellFounded using () renaming (wfRec to <-rec)
downFrom : Bin → List Bin -- x ∷ x-1 ∷ x-2 ∷ ... ∷ 0# ∷ []
downFrom = <-rec _ _ df
where
df : (b : Bin) → (∀ b′ → b′ < b → List Bin) → List Bin
df 0# dfRec = 0# ∷ []
df (bs 1#) dfRec = (bs 1#) ∷ (dfRec (predBin (bs 1#)) (predBin-< bs))
--------------------------------------------------------------
In order to use well-founded induction, we first have to prove that
the strict order < is indeed well-founded. Thankfully, the standard
library already contains such a proof for the strict order on (unary)
naturals as well as a collection of combinators for deriving
well-foundedness of relations from others (in this case the strict
order on unary naturals).
The core of the implementation of `downFrom' via well-founded
recursion is the function `df', which has the same signature as
`downFrom' except for the additional argument `dfRec', which serves as
the 'induction hypothesis'. The argument `dfRec' is itself a function
with (almost) the same signature as `downFrom' allowing us to make
recursive calls (i.e. take a recursive step), provided we can prove
that the first argument of the recursive call (i.e. the argument to
the induction hypothesis) is smaller than the first argument of the
enclosing call to `df'. The proof that this is indeed the case is
passed to `dfRec' as an additional argument of type b′ < b.
The following answer on Stackoverflow contains a nice explanation on
https://stackoverflow.com/a/19667260
Cheers
/Sandro
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Dear all,
I am trying to understand how to use WellFounded of Standard library.
Can anybody demonstrate it on the following example?
--------------------------------------------------------------
open import Function using (_∘_)
open import Data.List using (List; []; _∷_)
open import Data.Bin using (Bin; toBits; pred)
open Bin
predBin : Bin → Bin
predBin = pred ∘ toBits
downFrom : Bin → List Bin -- x ∷ x-1 ∷ x-2 ∷ ... ∷ 0# ∷ []
downFrom 0# = 0# ∷ []
downFrom (bs 1#) = (bs 1#) ∷ (downFrom (predBin (bs 1#)))
--------------------------------------------------------------
downFrom is not recognized as terminating.
How to reorganize it with using items from
Induction/*, WellFounded.agda ?
I presumed also that it is already given the property
postulate
predBin-< : (bs : List Bit) -> predBin (bs 1#) < (bs 1#)
(I do not mean to deal here with its proof).
--
SM
_______________________________________________
Agda mailing list
https://lists.chalmers.se/mailman/listinfo/agda
Arseniy Alekseyev
2018-08-09 22:15:58 UTC
Permalink
Something like this, I think:

P : Bin → Set
P _y = (x : Bin) → Bin

gc : (y : Bin) → (∀ y' → y' < y → P y') → P y

then after applying <-rec you get something of type [(y : Bin) → P y],
which is just gcd with arguments swapped.

(I wrote P in a general form so that it's more similar to "dependent"
examples, but of course you don't need to)
Post by Sergei Meshveliani
Thank you.
After this sample of downFrom I was able to program divMod for Bin.
But I am stuck with gcd for Bin.
------------------------------------------------------
postulate
rem : Bin → (y : Bin) → y ≢ 0# → Bin -- remainder of x by y.
rem< : (x y : Bin) → (y≢0 : y ≢ 0#) → rem x y y≢0 < y
gcd : Bin → Bin → Bin
gcd x y
with y ≟ 0#
... | yes _ = x
... | no y≢0 = gcd y (rem x y y≢0)
This lacks termination proof.
The argument pair (x , y) is replaced in recursion with (y , r),
gcd' : Bin → Bin → Bin
gcd' = <-rec _ _ gc
where
postulate
gc : Bin → (b : Bin) → (∀ x y → y < b → Bin) → Bin -- ??
I do not guess what signature to set for gc.
I set a hole "?" for gc, and the type checker shows
Induction.WellFounded.WfRec _<_ (λ _ → Bin → Bin)
.Relation.Unary._.⊆′ (λ _ → Bin → Bin)
-- ?
Can anybody help, please?
Thanks,
------
Sergei
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Can anybody demonstrate it on the following example?
--------------------------------------------------------------
open import Function using (_∘_; _on_)
open import Data.List using (List; []; _∷_)
open import Data.Bin using (Bin; toBits; pred; _<_; less; toℕ)
open import Data.Digit using (Bit)
import Data.Nat as Nat
import Induction.Nat as NatInd
open import Induction.WellFounded
open Bin
predBin : Bin → Bin
predBin = pred ∘ toBits
postulate
predBin-< : (bs : List Bit) -> predBin (bs 1#) < (bs 1#)
-- The strict order on binary naturals implies the strict order on the
-- corresponding unary naturals.
<⇒<ℕ : ∀ {b₁ b₂} → b₁ < b₂ → (Nat._<_ on toℕ) b₁ b₂
<⇒<ℕ (less lt) = lt
-- We can derive well-foundedness of _<_ on binary naturals from
-- well-foundedness of _<_ on unary naturals.
<-wellFounded : WellFounded _<_
<-wellFounded =
Subrelation.wellFounded <⇒<ℕ (Inverse-image.wellFounded toℕ
NatInd.<-wellFounded)
open All <-wellFounded using () renaming (wfRec to <-rec)
downFrom : Bin → List Bin -- x ∷ x-1 ∷ x-2 ∷ ... ∷ 0# ∷ []
downFrom = <-rec _ _ df
where
df : (b : Bin) → (∀ b′ → b′ < b → List Bin) → List Bin
df 0# dfRec = 0# ∷ []
df (bs 1#) dfRec = (bs 1#) ∷ (dfRec (predBin (bs 1#)) (predBin-< bs))
--------------------------------------------------------------
In order to use well-founded induction, we first have to prove that
the strict order < is indeed well-founded. Thankfully, the standard
library already contains such a proof for the strict order on (unary)
naturals as well as a collection of combinators for deriving
well-foundedness of relations from others (in this case the strict
order on unary naturals).
The core of the implementation of `downFrom' via well-founded
recursion is the function `df', which has the same signature as
`downFrom' except for the additional argument `dfRec', which serves as
the 'induction hypothesis'. The argument `dfRec' is itself a function
with (almost) the same signature as `downFrom' allowing us to make
recursive calls (i.e. take a recursive step), provided we can prove
that the first argument of the recursive call (i.e. the argument to
the induction hypothesis) is smaller than the first argument of the
enclosing call to `df'. The proof that this is indeed the case is
passed to `dfRec' as an additional argument of type b′ < b.
The following answer on Stackoverflow contains a nice explanation on
https://stackoverflow.com/a/19667260
Cheers
/Sandro
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Dear all,
I am trying to understand how to use WellFounded of Standard library.
Can anybody demonstrate it on the following example?
--------------------------------------------------------------
open import Function using (_∘_)
open import Data.List using (List; []; _∷_)
open import Data.Bin using (Bin; toBits; pred)
open Bin
predBin : Bin → Bin
predBin = pred ∘ toBits
downFrom : Bin → List Bin -- x ∷ x-1 ∷ x-2 ∷ ... ∷ 0# ∷ []
downFrom 0# = 0# ∷ []
downFrom (bs 1#) = (bs 1#) ∷ (downFrom (predBin (bs 1#)))
--------------------------------------------------------------
downFrom is not recognized as terminating.
How to reorganize it with using items from
Induction/*, WellFounded.agda ?
I presumed also that it is already given the property
postulate
predBin-< : (bs : List Bit) -> predBin (bs 1#) < (bs 1#)
(I do not mean to deal here with its proof).
--
SM
_______________________________________________
Agda mailing list
https://lists.chalmers.se/mailman/listinfo/agda
_______________________________________________
Agda mailing list
https://lists.chalmers.se/mailman/listinfo/agda
Sergei Meshveliani
2018-08-10 11:36:43 UTC
Permalink
P : Bin → Set
P _y = (x : Bin) → Bin
gc : (y : Bin) → (∀ y' → y' < y → P y') → P y
then after applying <-rec you get something of type [(y : Bin) → P y],
which is just gcd with arguments swapped.
(I wrote P in a general form so that it's more similar to "dependent"
examples, but of course you don't need to)
Thank you.
This works with the result of Bin.
I try to extend this to
gcd : (a b : Bin) -> GCD a b,
and fail.

------------------------------------------------------------------
postulate
rem : Bin → (y : Bin) → y ≢ 0# → Bin -- remainder of x by y.

rem< : (x y : Bin) → (y≢0 : y ≢ 0#) → rem x y y≢0 < y


record GCD (a b : Bin) : Set -- contrived
where
constructor gcd′

field res : Bin
divides-a : ∃ (\q → res * q ≡ a)
divides-b : ∃ (\q → res * q ≡ b)
--
-- and maximality axiom

-- Without using termination proof:
--
{-# TERMINATING #-}
gcd : (a b : Bin) → GCD a b
gcd x y
with x ≟ 0#
... | yes x≡0 = gcd′ y (0# , y*0≡x) (1# , y*1≡y)
where
postulate y*0≡x : y * 0# ≡ x
y*1≡y : y * 1# ≡ y

... | no x≢0 = liftGCD (gcd r x)
where
r = rem y x x≢0

postulate liftGCD : GCD r x → GCD x y
---------------------------------------------------------------

The second argument is divided by the first one in the loop -- this way
it is easier to use.

This is type-checked.

Now try WellFounded. As I understand, the approach is to reduce to a
function of a single argument:

---------------------------------------------------------------
gcd : (a : Bin) → GCD a
gcd = <-rec _ _ gc
where
gc : (x : Bin) → (∀ x' → x' < x → GCD x') → GCD x
gc x gcRec
with x ≟ 0#
... | yes x≡0 = f
where
f : GCD x
f y = gcd′ y (0# , y*0≡x) (1# , y*1≡y)
where
postulate y*0≡x : y * 0# ≡ x
y*1≡y : y * 1# ≡ y

... | no x≢0 = f
where
f : GCD x
f y = liftGCD (gcRec r r<x x)
where
r = rem y x x≢0
r<x = rem< x y x≢0

postulate liftGCD : GCD r x → GCD x y
---------------------------------------------------------------

Agda type-checks the function gc,
but it reports that (<-rec _ _ gc) does not return a value of the type
GCD a.

Then I try

gcd : Bin → (Bin → Set)
gcd = <-rec _ _ gc
where
postulate
gc : (x : Bin) → (∀ x' → x' < x → Bin → Set) → Bin → Set

(which goal adequacy I do not understand).
It is type-checked,
but I fail to implement this version of gc.

Can anybody advise, please?

------
Sergei
Thank you.
After this sample of downFrom I was able to program divMod
for Bin.
But I am stuck with gcd for Bin.
------------------------------------------------------
postulate
rem : Bin → (y : Bin) → y ≢ 0# → Bin -- remainder of x by y.
rem< : (x y : Bin) → (y≢0 : y ≢ 0#) → rem x y y≢0 < y
gcd : Bin → Bin → Bin
gcd x y
with y ≟ 0#
... | yes _ = x
... | no y≢0 = gcd y (rem x y y≢0)
This lacks termination proof.
The argument pair (x , y) is replaced in recursion with
(y , r),
gcd' : Bin → Bin → Bin
gcd' = <-rec _ _ gc
where
postulate
gc : Bin → (b : Bin) → (∀ x y → y < b → Bin) → Bin
-- ??
I do not guess what signature to set for gc.
I set a hole "?" for gc, and the type checker shows
Induction.WellFounded.WfRec _<_ (λ _ → Bin → Bin)
.Relation.Unary._.⊆′ (λ _ → Bin → Bin)
-- ?
Can anybody help, please?
Thanks,
------
Sergei
Post by Sandro Stucki
Post by Sergei Meshveliani
Can anybody demonstrate it on the following example?
--------------------------------------------------------------
Post by Sandro Stucki
open import Function using (_∘_; _on_)
open import Data.List using (List; []; _∷_)
open import Data.Bin using (Bin; toBits; pred; _<_; less;
toℕ)
Post by Sandro Stucki
open import Data.Digit using (Bit)
import Data.Nat as Nat
import Induction.Nat as NatInd
open import Induction.WellFounded
open Bin
predBin : Bin → Bin
predBin = pred ∘ toBits
postulate
predBin-< : (bs : List Bit) -> predBin (bs 1#) < (bs 1#)
-- The strict order on binary naturals implies the strict
order on the
Post by Sandro Stucki
-- corresponding unary naturals.
<⇒<ℕ : ∀ {b₁ b₂} → b₁ < b₂ → (Nat._<_ on toℕ) b₁ b₂
<⇒<ℕ (less lt) = lt
-- We can derive well-foundedness of _<_ on binary naturals
from
Post by Sandro Stucki
-- well-foundedness of _<_ on unary naturals.
<-wellFounded : WellFounded _<_
<-wellFounded =
Subrelation.wellFounded <⇒<ℕ (Inverse-image.wellFounded
toℕ
Post by Sandro Stucki
NatInd.<-wellFounded)
open All <-wellFounded using () renaming (wfRec to <-rec)
downFrom : Bin → List Bin -- x ∷ x-1 ∷ x-2 ∷ ... ∷ 0# ∷
[]
Post by Sandro Stucki
downFrom = <-rec _ _ df
where
df : (b : Bin) → (∀ b′ → b′ < b → List Bin) → List Bin
df 0# dfRec = 0# ∷ []
df (bs 1#) dfRec = (bs 1#) ∷ (dfRec (predBin (bs 1#))
(predBin-< bs))
--------------------------------------------------------------
Post by Sandro Stucki
In order to use well-founded induction, we first have to
prove that
Post by Sandro Stucki
the strict order < is indeed well-founded. Thankfully, the
standard
Post by Sandro Stucki
library already contains such a proof for the strict order
on (unary)
Post by Sandro Stucki
naturals as well as a collection of combinators for deriving
well-foundedness of relations from others (in this case the
strict
Post by Sandro Stucki
order on unary naturals).
The core of the implementation of `downFrom' via
well-founded
Post by Sandro Stucki
recursion is the function `df', which has the same signature
as
Post by Sandro Stucki
`downFrom' except for the additional argument `dfRec', which
serves as
Post by Sandro Stucki
the 'induction hypothesis'. The argument `dfRec' is itself a
function
Post by Sandro Stucki
with (almost) the same signature as `downFrom' allowing us
to make
Post by Sandro Stucki
recursive calls (i.e. take a recursive step), provided we
can prove
Post by Sandro Stucki
that the first argument of the recursive call (i.e. the
argument to
Post by Sandro Stucki
the induction hypothesis) is smaller than the first argument
of the
Post by Sandro Stucki
enclosing call to `df'. The proof that this is indeed the
case is
Post by Sandro Stucki
passed to `dfRec' as an additional argument of type b′ < b.
The following answer on Stackoverflow contains a nice
explanation on
Post by Sandro Stucki
https://stackoverflow.com/a/19667260
Cheers
/Sandro
On Wed, Aug 8, 2018 at 12:13 PM Sergei Meshveliani
Post by Sergei Meshveliani
On Tue, 2018-08-07 at 20:51 +0300, Sergei Meshveliani
Post by Sergei Meshveliani
Dear all,
I am trying to understand how to use WellFounded of
Standard library.
Post by Sandro Stucki
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Can anybody demonstrate it on the following example?
--------------------------------------------------------------
Post by Sandro Stucki
Post by Sergei Meshveliani
Post by Sergei Meshveliani
open import Function using (_∘_)
open import Data.List using (List; []; _∷_)
open import Data.Bin using (Bin; toBits; pred)
open Bin
predBin : Bin → Bin
predBin = pred ∘ toBits
downFrom : Bin → List Bin -- x ∷ x-1 ∷ x-2 ∷ ... ∷
0# ∷ []
Post by Sandro Stucki
Post by Sergei Meshveliani
Post by Sergei Meshveliani
downFrom 0# = 0# ∷ []
downFrom (bs 1#) = (bs 1#) ∷ (downFrom (predBin (bs
1#)))
--------------------------------------------------------------
Post by Sandro Stucki
Post by Sergei Meshveliani
Post by Sergei Meshveliani
downFrom is not recognized as terminating.
How to reorganize it with using items from
Induction/*, WellFounded.agda ?
I presumed also that it is already given the property
postulate
predBin-< : (bs : List Bit) -> predBin (bs 1#) < (bs
1#)
Post by Sandro Stucki
Post by Sergei Meshveliani
(I do not mean to deal here with its proof).
--
SM
_______________________________________________
Agda mailing list
https://lists.chalmers.se/mailman/listinfo/agda
_______________________________________________
Agda mailing list
https://lists.chalmers.se/mailman/listinfo/agda
Sergei Meshveliani
2018-08-10 12:35:39 UTC
Permalink
Post by Sergei Meshveliani
P : Bin → Set
P _y = (x : Bin) → Bin
gc : (y : Bin) → (∀ y' → y' < y → P y') → P y
then after applying <-rec you get something of type [(y : Bin) → P y],
which is just gcd with arguments swapped.
(I wrote P in a general form so that it's more similar to "dependent"
examples, but of course you don't need to)
Thank you.
This works with the result of Bin.
I try to extend this to
gcd : (a b : Bin) -> GCD a b,
and fail.
Below r<x = rem< x y x≢0
was a typo,
it needs to be replaced with r<x = rem< y x x≢0.

But this does not change the report of Agda.


Another attempt
===============

I change the signatures to

------------------------------------------
BB = Bin × Bin

_<p_ : Rel BB Level.zero
_<p_ = _<_ on proj₁

open import Induction.WellFounded using (WellFounded)

postulate <p-wellFounded : WellFounded _<p_

open All <p-wellFounded using () renaming (wfRec to <-rec)

record GCD (pr : BB) : Set -- contrived
where
constructor gcd′
a = proj₁ pr
b = proj₂ pr

field res : Bin
divides-a : ∃ (\q → res * q ≡ a)
divides-b : ∃ (\q → res * q ≡ b)
-- and maximality axiom

gcd : (pr : BB) → GCD pr
----------------------------------------------

Now gcd is on Bin × Bin, and your approach works,
the code is type-checked:

gcd = <-rec _ _ gc
where
gc : (pr : BB) → (∀ pr' → pr' <p pr → GCD pr') → GCD pr
gc (x , y) gcRec
with x ≟ 0#

... | no x≢0 = f
where
f : GCD (x , y)
f = liftGCD (gcRec (r , x) r<x)
where
r = rem y x x≢0
r<x = rem< y x x≢0

postulate liftGCD : GCD (r , x) → GCD (x , y)
... | ...
-------------------------------------------------


All right: I can convert from GCD-auxiliary (a , b)
to GCD a b.

But I have an impression that the WellFounded recursion thing is also
available directly for the signature of

gcd : (a b : Bin) → GCD a b,

only am missing something.
-- ?

Regards,

------
Sergei
Post by Sergei Meshveliani
------------------------------------------------------------------
postulate
rem : Bin → (y : Bin) → y ≢ 0# → Bin -- remainder of x by y.
rem< : (x y : Bin) → (y≢0 : y ≢ 0#) → rem x y y≢0 < y
record GCD (a b : Bin) : Set -- contrived
where
constructor gcd′
field res : Bin
divides-a : ∃ (\q → res * q ≡ a)
divides-b : ∃ (\q → res * q ≡ b)
--
-- and maximality axiom
--
{-# TERMINATING #-}
gcd : (a b : Bin) → GCD a b
gcd x y
with x ≟ 0#
... | yes x≡0 = gcd′ y (0# , y*0≡x) (1# , y*1≡y)
where
postulate y*0≡x : y * 0# ≡ x
y*1≡y : y * 1# ≡ y
... | no x≢0 = liftGCD (gcd r x)
where
r = rem y x x≢0
postulate liftGCD : GCD r x → GCD x y
---------------------------------------------------------------
The second argument is divided by the first one in the loop -- this way
it is easier to use.
This is type-checked.
Now try WellFounded. As I understand, the approach is to reduce to a
---------------------------------------------------------------
gcd : (a : Bin) → GCD a
gcd = <-rec _ _ gc
where
gc : (x : Bin) → (∀ x' → x' < x → GCD x') → GCD x
gc x gcRec
with x ≟ 0#
... | yes x≡0 = f
where
f : GCD x
f y = gcd′ y (0# , y*0≡x) (1# , y*1≡y)
where
postulate y*0≡x : y * 0# ≡ x
y*1≡y : y * 1# ≡ y
... | no x≢0 = f
where
f : GCD x
f y = liftGCD (gcRec r r<x x)
where
r = rem y x x≢0
r<x = rem< x y x≢0
postulate liftGCD : GCD r x → GCD x y
---------------------------------------------------------------
Agda type-checks the function gc,
but it reports that (<-rec _ _ gc) does not return a value of the type
GCD a.
Then I try
gcd : Bin → (Bin → Set)
gcd = <-rec _ _ gc
where
postulate
gc : (x : Bin) → (∀ x' → x' < x → Bin → Set) → Bin → Set
(which goal adequacy I do not understand).
It is type-checked,
but I fail to implement this version of gc.
Can anybody advise, please?
------
Sergei
Thank you.
After this sample of downFrom I was able to program divMod
for Bin.
But I am stuck with gcd for Bin.
------------------------------------------------------
postulate
rem : Bin → (y : Bin) → y ≢ 0# → Bin -- remainder of x
by y.
rem< : (x y : Bin) → (y≢0 : y ≢ 0#) → rem x y y≢0 < y
gcd : Bin → Bin → Bin
gcd x y
with y ≟ 0#
... | yes _ = x
... | no y≢0 = gcd y (rem x y y≢0)
This lacks termination proof.
The argument pair (x , y) is replaced in recursion with
(y , r),
gcd' : Bin → Bin → Bin
gcd' = <-rec _ _ gc
where
postulate
gc : Bin → (b : Bin) → (∀ x y → y < b → Bin) → Bin
-- ??
I do not guess what signature to set for gc.
I set a hole "?" for gc, and the type checker shows
Induction.WellFounded.WfRec _<_ (λ _ → Bin → Bin)
.Relation.Unary._.⊆′ (λ _ → Bin → Bin)
-- ?
Can anybody help, please?
Thanks,
------
Sergei
Post by Sandro Stucki
Post by Sergei Meshveliani
Can anybody demonstrate it on the following example?
--------------------------------------------------------------
Post by Sandro Stucki
open import Function using (_∘_; _on_)
open import Data.List using (List; []; _∷_)
open import Data.Bin using (Bin; toBits; pred; _<_; less;
toℕ)
Post by Sandro Stucki
open import Data.Digit using (Bit)
import Data.Nat as Nat
import Induction.Nat as NatInd
open import Induction.WellFounded
open Bin
predBin : Bin → Bin
predBin = pred ∘ toBits
postulate
predBin-< : (bs : List Bit) -> predBin (bs 1#) < (bs 1#)
-- The strict order on binary naturals implies the strict
order on the
Post by Sandro Stucki
-- corresponding unary naturals.
<⇒<ℕ : ∀ {b₁ b₂} → b₁ < b₂ → (Nat._<_ on toℕ) b₁ b₂
<⇒<ℕ (less lt) = lt
-- We can derive well-foundedness of _<_ on binary naturals
from
Post by Sandro Stucki
-- well-foundedness of _<_ on unary naturals.
<-wellFounded : WellFounded _<_
<-wellFounded =
Subrelation.wellFounded <⇒<ℕ (Inverse-image.wellFounded
toℕ
Post by Sandro Stucki
NatInd.<-wellFounded)
open All <-wellFounded using () renaming (wfRec to <-rec)
downFrom : Bin → List Bin -- x ∷ x-1 ∷ x-2 ∷ ... ∷ 0# ∷
[]
Post by Sandro Stucki
downFrom = <-rec _ _ df
where
df : (b : Bin) → (∀ b′ → b′ < b → List Bin) → List Bin
df 0# dfRec = 0# ∷ []
df (bs 1#) dfRec = (bs 1#) ∷ (dfRec (predBin (bs 1#))
(predBin-< bs))
--------------------------------------------------------------
Post by Sandro Stucki
In order to use well-founded induction, we first have to
prove that
Post by Sandro Stucki
the strict order < is indeed well-founded. Thankfully, the
standard
Post by Sandro Stucki
library already contains such a proof for the strict order
on (unary)
Post by Sandro Stucki
naturals as well as a collection of combinators for deriving
well-foundedness of relations from others (in this case the
strict
Post by Sandro Stucki
order on unary naturals).
The core of the implementation of `downFrom' via
well-founded
Post by Sandro Stucki
recursion is the function `df', which has the same signature
as
Post by Sandro Stucki
`downFrom' except for the additional argument `dfRec', which
serves as
Post by Sandro Stucki
the 'induction hypothesis'. The argument `dfRec' is itself a
function
Post by Sandro Stucki
with (almost) the same signature as `downFrom' allowing us
to make
Post by Sandro Stucki
recursive calls (i.e. take a recursive step), provided we
can prove
Post by Sandro Stucki
that the first argument of the recursive call (i.e. the
argument to
Post by Sandro Stucki
the induction hypothesis) is smaller than the first argument
of the
Post by Sandro Stucki
enclosing call to `df'. The proof that this is indeed the
case is
Post by Sandro Stucki
passed to `dfRec' as an additional argument of type b′ < b.
The following answer on Stackoverflow contains a nice
explanation on
Post by Sandro Stucki
https://stackoverflow.com/a/19667260
Cheers
/Sandro
On Wed, Aug 8, 2018 at 12:13 PM Sergei Meshveliani
Post by Sergei Meshveliani
On Tue, 2018-08-07 at 20:51 +0300, Sergei Meshveliani
Post by Sergei Meshveliani
Dear all,
I am trying to understand how to use WellFounded of
Standard library.
Post by Sandro Stucki
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Can anybody demonstrate it on the following example?
--------------------------------------------------------------
Post by Sandro Stucki
Post by Sergei Meshveliani
Post by Sergei Meshveliani
open import Function using (_∘_)
open import Data.List using (List; []; _∷_)
open import Data.Bin using (Bin; toBits; pred)
open Bin
predBin : Bin → Bin
predBin = pred ∘ toBits
downFrom : Bin → List Bin -- x ∷ x-1 ∷ x-2 ∷ ... ∷
0# ∷ []
Post by Sandro Stucki
Post by Sergei Meshveliani
Post by Sergei Meshveliani
downFrom 0# = 0# ∷ []
downFrom (bs 1#) = (bs 1#) ∷ (downFrom (predBin (bs
1#)))
--------------------------------------------------------------
Post by Sandro Stucki
Post by Sergei Meshveliani
Post by Sergei Meshveliani
downFrom is not recognized as terminating.
How to reorganize it with using items from
Induction/*, WellFounded.agda ?
I presumed also that it is already given the property
postulate
predBin-< : (bs : List Bit) -> predBin (bs 1#) < (bs
1#)
Post by Sandro Stucki
Post by Sergei Meshveliani
(I do not mean to deal here with its proof).
--
SM
_______________________________________________
Agda mailing list
https://lists.chalmers.se/mailman/listinfo/agda
_______________________________________________
Agda mailing list
https://lists.chalmers.se/mailman/listinfo/agda
_______________________________________________
Agda mailing list
https://lists.chalmers.se/mailman/listinfo/agda
Arseniy Alekseyev
2018-08-10 13:05:51 UTC
Permalink
Two things:

1.
In your first attempt you did not re-define GCD (or you skipped that from
your e-mail, but that seems to be the important part). The original
definition can't work because [GCD x] isn't even a type so nothing can ever
return a value of this type.
You need to define something like (I'll stubbornly keep calling this P for
similarity with other examples but you're free to call it whatever):
P : Bin → Set
P a = (b : Bin) → GCD a b

2. Giving P explicitly can help improve error messages a lot. You can try
something like this:
gcd = <-rec _ P gc

I haven't look in much detail so maybe this is not actually helpful. Sorry
if it's not.
WellFounded recursion thing is also available directly for the signature
of
gcd : (a b : Bin) → GCD a b,
It's only available for signatures of form [(x : X) → P a] for well-founded
X, so yes, that's the case. By unifying the two types you get exactly the P
I wrote above.
Post by Sergei Meshveliani
Post by Arseniy Alekseyev
P : Bin → Set
P _y = (x : Bin) → Bin
gc : (y : Bin) → (∀ y' → y' < y → P y') → P y
then after applying <-rec you get something of type [(y : Bin) → P y],
which is just gcd with arguments swapped.
(I wrote P in a general form so that it's more similar to "dependent"
examples, but of course you don't need to)
Thank you.
This works with the result of Bin.
I try to extend this to
gcd : (a b : Bin) -> GCD a b,
and fail.
Below r<x = rem< x y x≢0
was a typo,
it needs to be replaced with r<x = rem< y x x≢0.
But this does not change the report of Agda.
Another attempt
===============
I change the signatures to
------------------------------------------
BB = Bin × Bin
_<p_ : Rel BB Level.zero
_<p_ = _<_ on proj₁
open import Induction.WellFounded using (WellFounded)
postulate <p-wellFounded : WellFounded _<p_
open All <p-wellFounded using () renaming (wfRec to <-rec)
record GCD (pr : BB) : Set -- contrived
where
constructor gcd′
a = proj₁ pr
b = proj₂ pr
field res : Bin
divides-a : ∃ (\q → res * q ≡ a)
divides-b : ∃ (\q → res * q ≡ b)
-- and maximality axiom
gcd : (pr : BB) → GCD pr
----------------------------------------------
Now gcd is on Bin × Bin, and your approach works,
gcd = <-rec _ _ gc
where
gc : (pr : BB) → (∀ pr' → pr' <p pr → GCD pr') → GCD pr
gc (x , y) gcRec
with x ≟ 0#
... | no x≢0 = f
where
f : GCD (x , y)
f = liftGCD (gcRec (r , x) r<x)
where
r = rem y x x≢0
r<x = rem< y x x≢0
postulate liftGCD : GCD (r , x) → GCD (x , y)
... | ...
-------------------------------------------------
All right: I can convert from GCD-auxiliary (a , b)
to GCD a b.
But I have an impression that the WellFounded recursion thing is also
available directly for the signature of
gcd : (a b : Bin) → GCD a b,
only am missing something.
-- ?
Regards,
------
Sergei
Post by Sergei Meshveliani
------------------------------------------------------------------
postulate
rem : Bin → (y : Bin) → y ≢ 0# → Bin -- remainder of x by y.
rem< : (x y : Bin) → (y≢0 : y ≢ 0#) → rem x y y≢0 < y
record GCD (a b : Bin) : Set -- contrived
where
constructor gcd′
field res : Bin
divides-a : ∃ (\q → res * q ≡ a)
divides-b : ∃ (\q → res * q ≡ b)
--
-- and maximality axiom
--
{-# TERMINATING #-}
gcd : (a b : Bin) → GCD a b
gcd x y
with x ≟ 0#
... | yes x≡0 = gcd′ y (0# , y*0≡x) (1# , y*1≡y)
where
postulate y*0≡x : y * 0# ≡ x
y*1≡y : y * 1# ≡ y
... | no x≢0 = liftGCD (gcd r x)
where
r = rem y x x≢0
postulate liftGCD : GCD r x → GCD x y
---------------------------------------------------------------
The second argument is divided by the first one in the loop -- this way
it is easier to use.
This is type-checked.
Now try WellFounded. As I understand, the approach is to reduce to a
---------------------------------------------------------------
gcd : (a : Bin) → GCD a
gcd = <-rec _ _ gc
where
gc : (x : Bin) → (∀ x' → x' < x → GCD x') → GCD x
gc x gcRec
with x ≟ 0#
... | yes x≡0 = f
where
f : GCD x
f y = gcd′ y (0# , y*0≡x) (1# , y*1≡y)
where
postulate y*0≡x : y * 0# ≡ x
y*1≡y : y * 1# ≡ y
... | no x≢0 = f
where
f : GCD x
f y = liftGCD (gcRec r r<x x)
where
r = rem y x x≢0
r<x = rem< x y x≢0
postulate liftGCD : GCD r x → GCD x y
---------------------------------------------------------------
Agda type-checks the function gc,
but it reports that (<-rec _ _ gc) does not return a value of the type
GCD a.
Then I try
gcd : Bin → (Bin → Set)
gcd = <-rec _ _ gc
where
postulate
gc : (x : Bin) → (∀ x' → x' < x → Bin → Set) → Bin → Set
(which goal adequacy I do not understand).
It is type-checked,
but I fail to implement this version of gc.
Can anybody advise, please?
------
Sergei
Post by Arseniy Alekseyev
Thank you.
After this sample of downFrom I was able to program divMod
for Bin.
But I am stuck with gcd for Bin.
------------------------------------------------------
postulate
rem : Bin → (y : Bin) → y ≢ 0# → Bin -- remainder of x
by y.
rem< : (x y : Bin) → (y≢0 : y ≢ 0#) → rem x y y≢0 < y
gcd : Bin → Bin → Bin
gcd x y
with y ≟ 0#
... | yes _ = x
... | no y≢0 = gcd y (rem x y y≢0)
This lacks termination proof.
The argument pair (x , y) is replaced in recursion with
(y , r),
gcd' : Bin → Bin → Bin
gcd' = <-rec _ _ gc
where
postulate
gc : Bin → (b : Bin) → (∀ x y → y < b → Bin) → Bin
-- ??
I do not guess what signature to set for gc.
I set a hole "?" for gc, and the type checker shows
Induction.WellFounded.WfRec _<_ (λ _ → Bin → Bin)
.Relation.Unary._.⊆′ (λ _ → Bin → Bin)
-- ?
Can anybody help, please?
Thanks,
------
Sergei
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Can anybody demonstrate it on the following example?
--------------------------------------------------------------
Post by Sergei Meshveliani
open import Function using (_∘_; _on_)
open import Data.List using (List; []; _∷_)
open import Data.Bin using (Bin; toBits; pred; _<_; less;
toℕ)
Post by Sergei Meshveliani
open import Data.Digit using (Bit)
import Data.Nat as Nat
import Induction.Nat as NatInd
open import Induction.WellFounded
open Bin
predBin : Bin → Bin
predBin = pred ∘ toBits
postulate
predBin-< : (bs : List Bit) -> predBin (bs 1#) < (bs 1#)
-- The strict order on binary naturals implies the strict
order on the
Post by Sergei Meshveliani
-- corresponding unary naturals.
<⇒<ℕ : ∀ {b₁ b₂} → b₁ < b₂ → (Nat._<_ on toℕ) b₁ b₂
<⇒<ℕ (less lt) = lt
-- We can derive well-foundedness of _<_ on binary naturals
from
Post by Sergei Meshveliani
-- well-foundedness of _<_ on unary naturals.
<-wellFounded : WellFounded _<_
<-wellFounded =
Subrelation.wellFounded <⇒<ℕ (Inverse-image.wellFounded
toℕ
Post by Sergei Meshveliani
NatInd.<-wellFounded)
open All <-wellFounded using () renaming (wfRec to <-rec)
downFrom : Bin → List Bin -- x ∷ x-1 ∷ x-2 ∷ ... ∷ 0# ∷
[]
Post by Sergei Meshveliani
downFrom = <-rec _ _ df
where
df : (b : Bin) → (∀ b′ → b′ < b → List Bin) → List Bin
df 0# dfRec = 0# ∷ []
df (bs 1#) dfRec = (bs 1#) ∷ (dfRec (predBin (bs 1#))
(predBin-< bs))
--------------------------------------------------------------
Post by Sergei Meshveliani
In order to use well-founded induction, we first have to
prove that
Post by Sergei Meshveliani
the strict order < is indeed well-founded. Thankfully, the
standard
Post by Sergei Meshveliani
library already contains such a proof for the strict order
on (unary)
Post by Sergei Meshveliani
naturals as well as a collection of combinators for deriving
well-foundedness of relations from others (in this case the
strict
Post by Sergei Meshveliani
order on unary naturals).
The core of the implementation of `downFrom' via
well-founded
Post by Sergei Meshveliani
recursion is the function `df', which has the same signature
as
Post by Sergei Meshveliani
`downFrom' except for the additional argument `dfRec', which
serves as
Post by Sergei Meshveliani
the 'induction hypothesis'. The argument `dfRec' is itself a
function
Post by Sergei Meshveliani
with (almost) the same signature as `downFrom' allowing us
to make
Post by Sergei Meshveliani
recursive calls (i.e. take a recursive step), provided we
can prove
Post by Sergei Meshveliani
that the first argument of the recursive call (i.e. the
argument to
Post by Sergei Meshveliani
the induction hypothesis) is smaller than the first argument
of the
Post by Sergei Meshveliani
enclosing call to `df'. The proof that this is indeed the
case is
Post by Sergei Meshveliani
passed to `dfRec' as an additional argument of type b′ < b.
The following answer on Stackoverflow contains a nice
explanation on
Post by Sergei Meshveliani
https://stackoverflow.com/a/19667260
Cheers
/Sandro
On Wed, Aug 8, 2018 at 12:13 PM Sergei Meshveliani
Post by Sergei Meshveliani
On Tue, 2018-08-07 at 20:51 +0300, Sergei Meshveliani
Post by Sergei Meshveliani
Dear all,
I am trying to understand how to use WellFounded of
Standard library.
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Can anybody demonstrate it on the following example?
--------------------------------------------------------------
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Post by Sergei Meshveliani
open import Function using (_∘_)
open import Data.List using (List; []; _∷_)
open import Data.Bin using (Bin; toBits; pred)
open Bin
predBin : Bin → Bin
predBin = pred ∘ toBits
downFrom : Bin → List Bin -- x ∷ x-1 ∷ x-2 ∷ ... ∷
0# ∷ []
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Post by Sergei Meshveliani
downFrom 0# = 0# ∷ []
downFrom (bs 1#) = (bs 1#) ∷ (downFrom (predBin (bs
1#)))
--------------------------------------------------------------
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Post by Sergei Meshveliani
downFrom is not recognized as terminating.
How to reorganize it with using items from
Induction/*, WellFounded.agda ?
I presumed also that it is already given the property
postulate
predBin-< : (bs : List Bit) -> predBin (bs 1#) < (bs
1#)
Post by Sergei Meshveliani
Post by Sergei Meshveliani
(I do not mean to deal here with its proof).
--
SM
_______________________________________________
Agda mailing list
https://lists.chalmers.se/mailman/listinfo/agda
_______________________________________________
Agda mailing list
https://lists.chalmers.se/mailman/listinfo/agda
_______________________________________________
Agda mailing list
https://lists.chalmers.se/mailman/listinfo/agda
Arseniy Alekseyev
2018-08-10 13:06:23 UTC
Permalink
s/(x : X) → P a/(x : X) → P x/
Post by Arseniy Alekseyev
1.
In your first attempt you did not re-define GCD (or you skipped that from
your e-mail, but that seems to be the important part). The original
definition can't work because [GCD x] isn't even a type so nothing can ever
return a value of this type.
You need to define something like (I'll stubbornly keep calling this P for
P : Bin → Set
P a = (b : Bin) → GCD a b
2. Giving P explicitly can help improve error messages a lot. You can try
gcd = <-rec _ P gc
I haven't look in much detail so maybe this is not actually helpful. Sorry
if it's not.
WellFounded recursion thing is also available directly for the
signature of
gcd : (a b : Bin) → GCD a b,
It's only available for signatures of form [(x : X) → P a] for
well-founded X, so yes, that's the case. By unifying the two types you get
exactly the P I wrote above.
Post by Sergei Meshveliani
Post by Arseniy Alekseyev
P : Bin → Set
P _y = (x : Bin) → Bin
gc : (y : Bin) → (∀ y' → y' < y → P y') → P y
then after applying <-rec you get something of type [(y : Bin) → P y],
which is just gcd with arguments swapped.
(I wrote P in a general form so that it's more similar to "dependent"
examples, but of course you don't need to)
Thank you.
This works with the result of Bin.
I try to extend this to
gcd : (a b : Bin) -> GCD a b,
and fail.
Below r<x = rem< x y x≢0
was a typo,
it needs to be replaced with r<x = rem< y x x≢0.
But this does not change the report of Agda.
Another attempt
===============
I change the signatures to
------------------------------------------
BB = Bin × Bin
_<p_ : Rel BB Level.zero
_<p_ = _<_ on proj₁
open import Induction.WellFounded using (WellFounded)
postulate <p-wellFounded : WellFounded _<p_
open All <p-wellFounded using () renaming (wfRec to <-rec)
record GCD (pr : BB) : Set -- contrived
where
constructor gcd′
a = proj₁ pr
b = proj₂ pr
field res : Bin
divides-a : ∃ (\q → res * q ≡ a)
divides-b : ∃ (\q → res * q ≡ b)
-- and maximality axiom
gcd : (pr : BB) → GCD pr
----------------------------------------------
Now gcd is on Bin × Bin, and your approach works,
gcd = <-rec _ _ gc
where
gc : (pr : BB) → (∀ pr' → pr' <p pr → GCD pr') → GCD pr
gc (x , y) gcRec
with x ≟ 0#
... | no x≢0 = f
where
f : GCD (x , y)
f = liftGCD (gcRec (r , x) r<x)
where
r = rem y x x≢0
r<x = rem< y x x≢0
postulate liftGCD : GCD (r , x) → GCD (x , y)
... | ...
-------------------------------------------------
All right: I can convert from GCD-auxiliary (a , b)
to GCD a b.
But I have an impression that the WellFounded recursion thing is also
available directly for the signature of
gcd : (a b : Bin) → GCD a b,
only am missing something.
-- ?
Regards,
------
Sergei
Post by Sergei Meshveliani
------------------------------------------------------------------
postulate
rem : Bin → (y : Bin) → y ≢ 0# → Bin -- remainder of x by y.
rem< : (x y : Bin) → (y≢0 : y ≢ 0#) → rem x y y≢0 < y
record GCD (a b : Bin) : Set -- contrived
where
constructor gcd′
field res : Bin
divides-a : ∃ (\q → res * q ≡ a)
divides-b : ∃ (\q → res * q ≡ b)
--
-- and maximality axiom
--
{-# TERMINATING #-}
gcd : (a b : Bin) → GCD a b
gcd x y
with x ≟ 0#
... | yes x≡0 = gcd′ y (0# , y*0≡x) (1# , y*1≡y)
where
postulate y*0≡x : y * 0# ≡ x
y*1≡y : y * 1# ≡ y
... | no x≢0 = liftGCD (gcd r x)
where
r = rem y x x≢0
postulate liftGCD : GCD r x → GCD x y
---------------------------------------------------------------
The second argument is divided by the first one in the loop -- this way
it is easier to use.
This is type-checked.
Now try WellFounded. As I understand, the approach is to reduce to a
---------------------------------------------------------------
gcd : (a : Bin) → GCD a
gcd = <-rec _ _ gc
where
gc : (x : Bin) → (∀ x' → x' < x → GCD x') → GCD x
gc x gcRec
with x ≟ 0#
... | yes x≡0 = f
where
f : GCD x
f y = gcd′ y (0# , y*0≡x) (1# , y*1≡y)
where
postulate y*0≡x : y * 0# ≡ x
y*1≡y : y * 1# ≡ y
... | no x≢0 = f
where
f : GCD x
f y = liftGCD (gcRec r r<x x)
where
r = rem y x x≢0
r<x = rem< x y x≢0
postulate liftGCD : GCD r x → GCD x y
---------------------------------------------------------------
Agda type-checks the function gc,
but it reports that (<-rec _ _ gc) does not return a value of the type
GCD a.
Then I try
gcd : Bin → (Bin → Set)
gcd = <-rec _ _ gc
where
postulate
gc : (x : Bin) → (∀ x' → x' < x → Bin → Set) → Bin → Set
(which goal adequacy I do not understand).
It is type-checked,
but I fail to implement this version of gc.
Can anybody advise, please?
------
Sergei
Post by Arseniy Alekseyev
Thank you.
After this sample of downFrom I was able to program divMod
for Bin.
But I am stuck with gcd for Bin.
------------------------------------------------------
postulate
rem : Bin → (y : Bin) → y ≢ 0# → Bin -- remainder of x
by y.
rem< : (x y : Bin) → (y≢0 : y ≢ 0#) → rem x y y≢0 < y
gcd : Bin → Bin → Bin
gcd x y
with y ≟ 0#
... | yes _ = x
... | no y≢0 = gcd y (rem x y y≢0)
This lacks termination proof.
The argument pair (x , y) is replaced in recursion with
(y , r),
gcd' : Bin → Bin → Bin
gcd' = <-rec _ _ gc
where
postulate
gc : Bin → (b : Bin) → (∀ x y → y < b → Bin) → Bin
-- ??
I do not guess what signature to set for gc.
I set a hole "?" for gc, and the type checker shows
Induction.WellFounded.WfRec _<_ (λ _ → Bin → Bin)
.Relation.Unary._.⊆′ (λ _ → Bin → Bin)
-- ?
Can anybody help, please?
Thanks,
------
Sergei
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Can anybody demonstrate it on the following example?
--------------------------------------------------------------
Post by Sergei Meshveliani
open import Function using (_∘_; _on_)
open import Data.List using (List; []; _∷_)
open import Data.Bin using (Bin; toBits; pred; _<_; less;
toℕ)
Post by Sergei Meshveliani
open import Data.Digit using (Bit)
import Data.Nat as Nat
import Induction.Nat as NatInd
open import Induction.WellFounded
open Bin
predBin : Bin → Bin
predBin = pred ∘ toBits
postulate
predBin-< : (bs : List Bit) -> predBin (bs 1#) < (bs 1#)
-- The strict order on binary naturals implies the strict
order on the
Post by Sergei Meshveliani
-- corresponding unary naturals.
<⇒<ℕ : ∀ {b₁ b₂} → b₁ < b₂ → (Nat._<_ on toℕ) b₁ b₂
<⇒<ℕ (less lt) = lt
-- We can derive well-foundedness of _<_ on binary naturals
from
Post by Sergei Meshveliani
-- well-foundedness of _<_ on unary naturals.
<-wellFounded : WellFounded _<_
<-wellFounded =
Subrelation.wellFounded <⇒<ℕ (Inverse-image.wellFounded
toℕ
Post by Sergei Meshveliani
NatInd.<-wellFounded)
open All <-wellFounded using () renaming (wfRec to <-rec)
downFrom : Bin → List Bin -- x ∷ x-1 ∷ x-2 ∷ ... ∷ 0# ∷
[]
Post by Sergei Meshveliani
downFrom = <-rec _ _ df
where
df : (b : Bin) → (∀ b′ → b′ < b → List Bin) → List Bin
df 0# dfRec = 0# ∷ []
df (bs 1#) dfRec = (bs 1#) ∷ (dfRec (predBin (bs 1#))
(predBin-< bs))
--------------------------------------------------------------
Post by Sergei Meshveliani
In order to use well-founded induction, we first have to
prove that
Post by Sergei Meshveliani
the strict order < is indeed well-founded. Thankfully, the
standard
Post by Sergei Meshveliani
library already contains such a proof for the strict order
on (unary)
Post by Sergei Meshveliani
naturals as well as a collection of combinators for deriving
well-foundedness of relations from others (in this case the
strict
Post by Sergei Meshveliani
order on unary naturals).
The core of the implementation of `downFrom' via
well-founded
Post by Sergei Meshveliani
recursion is the function `df', which has the same signature
as
Post by Sergei Meshveliani
`downFrom' except for the additional argument `dfRec', which
serves as
Post by Sergei Meshveliani
the 'induction hypothesis'. The argument `dfRec' is itself a
function
Post by Sergei Meshveliani
with (almost) the same signature as `downFrom' allowing us
to make
Post by Sergei Meshveliani
recursive calls (i.e. take a recursive step), provided we
can prove
Post by Sergei Meshveliani
that the first argument of the recursive call (i.e. the
argument to
Post by Sergei Meshveliani
the induction hypothesis) is smaller than the first argument
of the
Post by Sergei Meshveliani
enclosing call to `df'. The proof that this is indeed the
case is
Post by Sergei Meshveliani
passed to `dfRec' as an additional argument of type b′ < b.
The following answer on Stackoverflow contains a nice
explanation on
Post by Sergei Meshveliani
https://stackoverflow.com/a/19667260
Cheers
/Sandro
On Wed, Aug 8, 2018 at 12:13 PM Sergei Meshveliani
Post by Sergei Meshveliani
On Tue, 2018-08-07 at 20:51 +0300, Sergei Meshveliani
Post by Sergei Meshveliani
Dear all,
I am trying to understand how to use WellFounded of
Standard library.
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Can anybody demonstrate it on the following example?
--------------------------------------------------------------
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Post by Sergei Meshveliani
open import Function using (_∘_)
open import Data.List using (List; []; _∷_)
open import Data.Bin using (Bin; toBits; pred)
open Bin
predBin : Bin → Bin
predBin = pred ∘ toBits
downFrom : Bin → List Bin -- x ∷ x-1 ∷ x-2 ∷ ... ∷
0# ∷ []
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Post by Sergei Meshveliani
downFrom 0# = 0# ∷ []
downFrom (bs 1#) = (bs 1#) ∷ (downFrom (predBin (bs
1#)))
--------------------------------------------------------------
Post by Sergei Meshveliani
Post by Sergei Meshveliani
Post by Sergei Meshveliani
downFrom is not recognized as terminating.
How to reorganize it with using items from
Induction/*, WellFounded.agda ?
I presumed also that it is already given the property
postulate
predBin-< : (bs : List Bit) -> predBin (bs 1#) < (bs
1#)
Post by Sergei Meshveliani
Post by Sergei Meshveliani
(I do not mean to deal here with its proof).
--
SM
_______________________________________________
Agda mailing list
https://lists.chalmers.se/mailman/listinfo/agda
_______________________________________________
Agda mailing list
https://lists.chalmers.se/mailman/listinfo/agda
_______________________________________________
Agda mailing list
https://lists.chalmers.se/mailman/listinfo/agda
Sergei Meshveliani
2018-08-10 14:20:32 UTC
Permalink
s/(x : X) → P a/(x : X) → P x/
On Fri, 10 Aug 2018 at 14:05, Arseniy Alekseyev
1.
In your first attempt you did not re-define GCD (or you
skipped that from your e-mail, but that seems to be the
important part). The original definition can't work because
[GCD x] isn't even a type so nothing can ever return a value
of this type.
I see now.
You need to define something like (I'll stubbornly keep
calling this P for similarity with other examples but you're
P : Bin → Set
P a = (b : Bin) → GCD a b
[..]
Great! Thank you very much. It works:

-------------------------------------------------
P : Bin → Set
P a = (b : Bin) → GCD a b

gcd : (a : Bin) → P a
gcd = <-rec _ P gc
where
gc : (x : Bin) → (∀ x' → x' < x → P x') → P x
gc x gcRec
with x ≟ 0#

... | no x≢0 = f
where
f : P x
f y = liftGCD (gcRec r r<x x)
where
r = rem y x x≢0
r<x = rem< y x x≢0

postulate liftGCD : GCD r x → GCD x y
... | ...
---------------------------------------------------


------
Sergei

Loading...