[Agda] using Induction.Nat

Andreas Abel andreas.abel at ifi.lmu.de
Tue Oct 8 05:10:58 CEST 2013


Using Data.Bin was also my hunch.  Here is a partial solution to your 
problem:

open import Function
open import Data.Bool
open import Data.List
open import Data.Nat
open import Data.Fin using (zero; suc)
open import Data.Bin using (Bin⁺; 0#; _1#; fromℕ)

open import Relation.Binary.PropositionalEquality

-- Binary exponentiation

module Power {A : Set} (_•_ : A → A → A) (x : A) where

   binPower : Bin⁺ → A
   binPower []       = x
   binPower (b ∷ bs) = case b of
       λ { zero           → r²
         ; (suc zero)     → x • r²
         ; (suc (suc ()))
         }
     where
       r  = binPower bs
       r² = r • r

   posPower : (n : ℕ) → n > 0 → A
   posPower 0 ()
   posPower (suc n) _ with fromℕ (1 + n)
   ... | bs 1# = binPower bs
   ... | 0#    = x  -- this case is impossible; showing this is extra 
work...



On 2013-10-08 10:13, Daniel Peebles wrote:
> My first inclination for your repeated halving is to switch to a
> representation where your work is structural Data.Bin comes to mind,
> and you could write your exponentiation algorithm on Bin values, then
> convert back and forth on the way in and out as a wrapper. It'd
> probably be a lot more efficient, too.
>
> Alternately, since the conversion to Data.Bin is doing well-founded
> recursion of the sort you need, you could use it as an example. The
> real work is done in Data.Digits, and you can find more
> at http://www.cse.chalmers.se/~nad/listings/lib/Data.Digit.html#2612
> [2].
>
> On Mon, Oct 7, 2013 at 10:30 AM, Sergei Meshveliani 
> <mechvel at botik.ru> wrote:
>
>> People,
>> I have this program for powering  x^(n+1)
>> for  x : Carrier of a Semigroup:
>>
>>  half : ℕ → ℕ
>>  half = ⌊_/2⌋
>>
>>  powerTo-suc : C → (e : ℕ) → C     -- x^(e+1)
>>  powerTo-suc x 0       = x
>>  powerTo-suc x (suc e) = case  even? e  of
>>                                         { (yes _) → p ∙ p
>>                                         ; _       → x ∙ (p ∙ p) }
>>                                         where
>>                                         h = half e
>>                                         p = powerTo-suc x h
>>
>> The checker cannot prove its termination.
>> I can help this proof by adding the counter argument  cnt  for the
>> number of the  `half'  calls.
>> But this complicates various further proofs for  powerTo-suc.
>>
>> So, I think of trying _inductive families_ for  ℕ  provided by
>> Induction, Induction.Nat ... in the standard library
>> (the question of whether this will make further proofs easier is 
>> open
>> for me).
>>
>> But it is difficult to understand the idea, some introductory text 
>> is
>> needed, with a couple of simple examples.
>>
>> Induction.Nat  gives an example for  `half'. It is too simple, 
>> because
>> it is for the step from  n  to  suc n.
>> And in my example, it is the step from  half (suc e)  to  suc e,
>> assuming that we have a proof for
>>                                   half (suc e) < suc e.
>>
>> Probably  cRec  needs here to be given something additional, maybe 
>> some
>> builder needs to be defined.
>>
>> May be you can demonstrate this Agda induction right on this example 
>> of
>> powerTo-suc ?
>>
>> Thank you in advance for explanation.
>>
>> ------
>> Sergei
>>
>> _______________________________________________
>> Agda mailing list
>> Agda at lists.chalmers.se
>> https://lists.chalmers.se/mailman/listinfo/agda [1]
>
>
>
> Links:
> ------
> [1] https://lists.chalmers.se/mailman/listinfo/agda
> [2] http://www.cse.chalmers.se/~nad/listings/lib/Data.Digit.html#2612
>
> _______________________________________________
> Agda mailing list
> Agda at lists.chalmers.se
> https://lists.chalmers.se/mailman/listinfo/agda

-- 
Andreas Abel  <><     Du bist der geliebte Mensch.

Theoretical Computer Science, University of Munich 
http://www.tcs.informatik.uni-muenchen.de/~abel/
-------------- next part --------------
module BinPowerStdLib where

open import Function
open import Data.Bool
open import Data.List
open import Data.Nat
open import Data.Fin using (zero; suc)
open import Data.Bin using (Bin⁺; 0#; _1#; fromℕ)

open import Relation.Binary.PropositionalEquality

-- Binary exponentiation

module Power {A : Set} (_•_ : A → A → A) (x : A) where

  binPower : Bin⁺ → A
  binPower []       = x
  binPower (b ∷ bs) = case b of
      λ { zero           → r²
        ; (suc zero)     → x • r²
        ; (suc (suc ()))
        }
    where
      r  = binPower bs
      r² = r • r

  posPower : (n : ℕ) → n > 0 → A
  posPower 0 ()
  posPower (suc n) _ with fromℕ (1 + n)
  ... | bs 1# = binPower bs
  ... | 0#    = x  -- this case is impossible; showing this is extra work...


More information about the Agda mailing list