How do i implement positive numbers in agda - agda

So im trying to define the set of positive natural numbers {1, 2, 3, . . .} in
Agda.
data Nat : Set where
one : Nat
succ : Nat -> Nat
{-#BUILTIN NATURAL Nat #-}
this is how i did it, but it still takes 0 with it.
how do u make it start from 1 ?

Agda allows to overload number literals via the FROMNAT built-in:
open import Agda.Builtin.Nat
open import Data.Empty
open import Data.Unit.Base
Positive : Nat -> Set
Positive zero = ⊥
Positive _ = ⊤
data Nat₁ : Set where
one : Nat₁
succ : Nat₁ -> Nat₁
toNat₁ : ∀ n {_ : Positive n} -> Nat₁
toNat₁ 0 {()}
toNat₁ 1 = one
toNat₁ (suc (suc n)) = succ (toNat₁ (suc n))
{-# BUILTIN FROMNAT toNat₁ #-}
fail : Nat₁
fail = 0
ok : Nat₁
ok = 1
Here Positive n is a constraint which is unsatisfiable when n is 0 and trivially satisfiable when n is positive. So in fail the constraint computes to ⊥ and you get an unsolved meta of this type, which is impossible to solve (assuming the type system is consistent), because this type is uninhabited.

Related

How to choose the design for a well-founded inductive type?

While studying well-foundedness, I wanted to see how different designs behave. For example, for a type:
data _<_ (x : Nat) : Nat -> Set where
<-b : x < (suc x)
<-s : (y : Nat) -> x < y -> x < (suc y)
well-foundedness is easy to demonstrate. But if a similar type is defined differently:
data _<_ : Nat -> Nat -> Set where
z-< : (m : Nat) -> zero < (suc m)
s<s : (m n : Nat) -> m < n -> (suc m) < (suc n)
It is obvious that in both cases the descending chain is not infinite, but in the second case well-foundedness is not easy to demonstrate: it is not easy to show (y -> y < x -> Acc y) exists for a given x.
Are there some principles that help choose the designs like the first in preference to the designs like the second?
It's not impossibly hard to prove well-foundedness of the second definition, it just requires extra theorems. Here, relying on decidability of _==_ for Nat, we can construct new _<_ for the case (suc y) != x, and can rewrite the target types to use the solution to the problem known to decrease in size as the solution for suc y.
-- trying to express well-foundedness is tricky, because of how x < y is defined:
-- since both x and y decrease in the inductive step case, need special effort to
-- prove when the induction stops - when no more constructors are available
<-Well-founded : Well-founded Nat _<_
<-Well-founded x = acc (aux x) where
aux : (x y : Nat) -> y < x -> Acc _<_ y
aux zero y ()
aux x zero z-< = acc \_ ()
aux (suc x) (suc y) (s<s y<x) with is-eq? (suc y) x
... | no sy!=x = aux x (suc y) (neq y<x sy!=x)
... | yes sy==x rewrite sy==x = <-Well-founded x
The first definition is "canonical" in a sense, while the second one is not. In Agda, every inductive type has a subterm relation which is well-founded and transitive, although not necessarily total, decidable or proof-irrelevant. For W-types, it's the following:
open import Data.Product
open import Data.Sum
open import Relation.Binary.PropositionalEquality
data W (S : Set)(P : S → Set) : Set where
lim : ∀ s → (P s → W S P) → W S P
_<_ : ∀ {S P} → W S P → W S P → Set
a < lim s f = ∃ λ p → a ≡ f p ⊎ a < f p
If we define Nat as a W-type, then the generic _<_ is the same as the first definition. The first definition establishes a subterm relation even if we have no idea about the constructors of Nat. The second definition is only a subterm relation because we know that zero is reachable from every suc n. If we added an extra zero' : Nat constructor, then this would not be the case anymore.

How to convince the Agda compiler that an expression terminates?

I'm learning Agda using Philip Wadler's Programming Language Foundations In Agda, and I can't figure out how to convince the compiler that a computation terminates.
I've got types for unary and binary naturals:
data ℕ : Set where
zero : ℕ
suc : ℕ → ℕ
data Bin : Set where
⟨⟩ : Bin
_O : Bin → Bin
_I : Bin → Bin
And I wrote a function to convert between the two representations (using some helpers):
-- try to count to a given power of two
--
-- to-count m t f n =
-- t (n - 2^m) if n >= 2^m
-- (f * 2^m) + n otherwise
to-count : ℕ → (ℕ → Bin) → Bin → ℕ → Bin
to-count zero t f zero = f
to-count zero t f (suc n) = t n
to-count (suc m) t f n = to-count m (to-count m t (f I)) (f O) n
-- keep trying to count bigger and bigger powers of two
to-next : ℕ → ℕ → Bin
to-next m = to-count m (to-next (suc m)) (⟨⟩ I)
to : ℕ → Bin
to = to-count zero (to-next zero) ⟨⟩
Later, when trying to prove that my conversion is faithful:
import Relation.Binary.PropositionalEquality as Eq
open Eq using (_≡_; refl; cong)
open Eq.≡-Reasoning using (begin_; _≡⟨⟩_; _≡⟨_⟩_; _∎)
_ : to zero ≡ ⟨⟩
_ = refl
_ : to (suc zero) ≡ ⟨⟩ I
_ = refl
The compiler complains that termination checking failed:
Checking Naturals (Naturals.agda).
Naturals.agda:23,1-24,48
Termination checking failed for the following functions:
to-next
Problematic calls:
to-next (suc m)
(at Naturals.agda:24,25-32)
Naturals.agda:37,5-9
to-next zero zero != ⟨⟩ I of type Bin
when checking that the expression refl has type
to (suc zero) ≡ (⟨⟩ I)
What are some strategies I can use to help convince the compiler that it terminates?
Using pragma is not how you need to convince the compiler that the function terminates.
The compiler indicated the problematic call: to-next (suc m) cannot be seen as unused in the cases you think, and obviously it creates a structurally bigger value than on input.
A way to deal with this problem is express the construction of Bin from ℕ differently.
inc-bin : Bin -> Bin
inc-bin ⟨⟩ = ⟨⟩ I
inc-bin (bb O) = bb I
inc-bin (bb I) = (inc-bin bb) O
to-bin-daft : ℕ -> Bin
to-bin-daft zero = b O
to-bin-daft (suc m) = inc-bin (to-bin-daft m)
This is "daft", as it literally increments Bin by one at a time, for every suc, but more complex algorithms involving, say, division by 2, require evidence that the result of division is smaller than the input.
Not sure if this is the most idiomatic solution, but I got it working using the TERMINATING pragma:
{-# TERMINATING #-}
to-next : ℕ → ℕ → Bin
to-next m = to-count m (to-next (suc m)) (⟨⟩ I)

How do I talk about a particular constructor in Agda

Say I have
data Maybe : Set -> Set where
Just : forall {A} -> A -> Maybe A
Nothing : forall {A} -> Maybe A
and I define my own minus like
minus : Nat -> Nat -> Maybe Nat
minus zero zero = Just zero
minus zero _ = Nothing
minus n zero = Just n
minus (suc n) (suc m) = minus n m
and I would like to prove that forall m n, if m > n, (minus m n) always spits out a (Just Nat).
I am wondering how I can encode this claim in a type.
Thank you!
You can use the standard library's Is-just. Your statement will look like:
lt-minus-total : ∀ n m → m < n → Is-just (minus n m)

About the image of the succ function

I defined the natural numbers as usually:
data Nat : Set where
zero : Nat
succ : Nat → Nat
and i.e the number one should be
one : Nat
one = succ zero
Later on, we can define the image datatype,
data Image_∋_ {A B : Set} (f : A → B) : B -> Set where
im : (x : A) → Image f ∋ (f x)
And to prove something like "the one is in the Image of the successor function" I wrote:
one-succ : Image succ ∋ one
one-succ = im zero
I would like to have the following.
Define the predecessor function that not allowed zero as an input just its successors. So the next is not valid.
pred : Nat → Nat
pred zero = zero
pred (succ n) = n
I would like to have a variable called Z⁺ representing the positive numbers but using in its definition the image of successor function (Image_∋_ data type defined above).
Image f ∋ y reads as "there is some x such that y ≡ f x". Pattern matching on Image f ∋ y by im x reveals the x.
So an element of type Image succ ∋ n is a proof that n is of the form succ m where m is carried inside that element. Hence the definition is simply
ipred : ∀ {n} → Image succ ∋ n → Nat
ipred (im m) = m
because n ≡ succ m and the predecessor of succ m is m.
It reads nicer if we rename im to isucc:
open Image_∋_ renaming (im to isucc)
ipred : ∀ {n} → Image succ ∋ n → Nat
ipred (isucc m) = m
Another way of writing the same thing is
data Image_∋_ {A B : Set} : (A → B) → B → Set where
_·_ : (f : A → B) → (x : A) → Image f ∋ f x
pred : ∀ {n} → Image succ ∋ n → Nat
pred (.succ · m) = m
Here f in Image f ∋ y is an index rather than a parameter, so _·_ (previously im) now receives two arguments: a function and its argument. It's not possible to pattern match on functions, but .succ is an "irrefutable pattern", i.e. it says "f can be nothing, but succ".
Nat⁺ can be defined as
data Nat⁺ : Set where
nat⁺ : ∀ {n} → Image succ ∋ n → Nat⁺
succ⁺ receives a natural number (implicitly) and a proof that this number is of the form succ m for some m.
You can always take the predecessor of a positive natural number:
pred⁺ : Nat⁺ → Nat
pred⁺ (nat⁺ (im m)) = m
But since Nat⁺ is a non-indexed one-constructor data type, it can be defined as a record:
record Nat⁺ : Set where
constructor nat⁺
field
{pred⁺} : Nat
image : Image succ ∋ pred⁺
open Nat⁺
open Nat⁺ introduces pred⁺ : Nat⁺ → Nat in scope.

Instance Implicits for Type Checking

I am learning how "typeclasses" are implemented in Agda. As an example, I am trying to implement Roman numerals whose composition with # would type-check.
I am not clear why Agda complains there is no instance for Join (Roman _ _) (Roman _ _) _ - clearly, it couldn't work out what natural numbers to substitute there.
Is there a nicer way to introduce Roman numbers that don't have "constructor" form? I have a constructor "madeup", which probably would need to be private, to be sure I have only "trusted" ways to construct other Roman numbers through Join.
module Romans where
data ℕ : Set where
zero : ℕ
succ : ℕ → ℕ
infixr 4 _+_ _*_ _#_
_+_ : ℕ → ℕ → ℕ
zero + x = x
succ y + x = succ (y + x)
_*_ : ℕ → ℕ → ℕ
zero * x = zero
succ y * x = x + (y * x)
one = succ zero
data Roman : ℕ → ℕ → Set where
i : Roman one one
{- v : Roman one five
x : Roman ten one
... -}
madeup : ∀ {a b} (x : Roman a b) → (c : ℕ) → Roman a c
record Join (A B C : Set) : Set where
field jo : A → B → C
two : ∀ {a} → Join (Roman a one) (Roman a one) (Roman a (one + one))
two = record { jo = λ l r → madeup l (one + one) }
_#_ : ∀ {a b c d C} → {{j : Join (Roman a b) (Roman c d) C}} → Roman a b → Roman c d → C
(_#_) {{j}} = Join.jo j
-- roman = (_#_) {{two}} i i -- works
roman : Roman one (one + one)
roman = {! i # i!} -- doesn't work
Clearly, if I specify the implicit explicitly, it works - so I am confident it is not the type of the function that is wrong.
Your example works fine in development version of Agda. If you are using a version older than 2.3.2, this passage from release notes could clarify why it doesn't compile for you:
* Instance arguments resolution will now consider candidates which
still expect hidden arguments. For example:
record Eq (A : Set) : Set where
field eq : A → A → Bool
open Eq {{...}}
eqFin : {n : ℕ} → Eq (Fin n)
eqFin = record { eq = primEqFin }
testFin : Bool
testFin = eq fin1 fin2
The type-checker will now resolve the instance argument of the eq
function to eqFin {_}. This is only done for hidden arguments, not
instance arguments, so that the instance search stays non-recursive.
(source)
That is, before 2.3.2, the instance search would completly ignore your two instance because it has a hidden argument.
While instance arguments behave a bit like type classes, note that they will only commit to an instance if there's only one type correct version in scope and they will not perform a recursive search:
Instance argument resolution is not recursive. As an example,
consider the following "parametrised instance":
eq-List : {A : Set} → Eq A → Eq (List A)
eq-List {A} eq = record { equal = eq-List-A }
where
eq-List-A : List A → List A → Bool
eq-List-A [] [] = true
eq-List-A (a ∷ as) (b ∷ bs) = equal a b ∧ eq-List-A as bs
eq-List-A _ _ = false
Assume that the only Eq instances in scope are eq-List and eq-ℕ.
Then the following code does not type-check:
test = equal (1 ∷ 2 ∷ []) (3 ∷ 4 ∷ [])
However, we can make the code work by constructing a suitable
instance manually:
test′ = equal (1 ∷ 2 ∷ []) (3 ∷ 4 ∷ [])
where eq-List-ℕ = eq-List eq-ℕ
By restricting the "instance search" to be non-recursive we avoid
introducing a new, compile-time-only evaluation model to Agda.
(source)
Now, as for the second part of the question: I'm not exactly sure what your final goal is, the structure of the code ultimately depends on what you want to do once you construct the number. That being said, I wrote down a small program that allows you to enter roman numerals without going through the explicit data type (forgive me if I didn't catch your intent clearly):
A roman numeral will be a function which takes a pair of natural numbers - the value of previous numeral and the running total. If it's smaller than previous numeral, we'll subtract its value from the running total, otherwise we add it up. We return the new running total and value of current numeral.
Of course, this is far from perfect, because there's nothing to prevent us from typing I I X and we end up evaluating this as 10. I leave this as an exercise for the interested reader. :)
Imports first (note that I'm using the standard library here, if you do not want to install it, you can just copy the definition from the online repo):
open import Data.Bool
open import Data.Nat
open import Data.Product
open import Relation.Binary
open import Relation.Nullary.Decidable
This is our numeral factory:
_<?_ : Decidable _<_
m <? n = suc m ≤? n
makeNumeral : ℕ → ℕ × ℕ → ℕ × ℕ
makeNumeral n (p , c) with ⌊ n <? p ⌋
... | true = n , c ∸ n
... | false = n , c + n
And we can make a few numerals:
infix 500 I_ V_ X_
I_ = makeNumeral 1
V_ = makeNumeral 5
X_ = makeNumeral 10
Next, we have to apply this chain of functions to something and then extract the running total. This is not the greatest solution, but it looks nice in code:
⟧ : ℕ × ℕ
⟧ = 0 , 0
infix 400 ⟦_
⟦_ : ℕ × ℕ → ℕ
⟦ (_ , c) = c
And finally:
test₁ : ℕ
test₁ = ⟦ X I X ⟧
test₂ : ℕ
test₂ = ⟦ X I V ⟧
Evaluating test₁ via C-c C-n gives us 19, test₂ then 14.
Of course, you can move these invariants into the data type, add new invariants and so on.

Resources