Termination check of a recursive function call in agda - recursion

The following code is perfectly ok in Haskell:
dh :: Int -> Int -> (Int, Int)
dh d q = (2^d, q^d)
a = dh 2 (fst b)
b = dh 3 (fst a)
Similiar code in Agda wouldn't compile (termination check fails):
infixl 9 _^_
_^_ : ℕ → ℕ → ℕ
x ^ zero = 1
x ^ suc n = x * (x ^ n)
dh : ℕ -> ℕ -> ℕ × ℕ
dh d q = 2 ^ d , q ^ d
mutual
a = dh 2 (proj₁ b)
b = dh 3 (proj₁ a)
The definition of a uses a which is not structurally smaller, hence the loop. It seems that the termination checker wouldn't look inside the definition of dh.
I've tried using coinduction, setting option --termination-depth=4 -- doesn't help.
Inserting {-# NO_TERMINATION_CHECK #-} within the mutual block helps but it looks like a cheat.
Is there a clean way to make Agda compile the code? Does Agda's termination checker have some fundamental limitations?

Agda doesn't assume lazy evaluation like Haskell does. Instead, Agda requires that all expressions be strongly normalizing. That means you should get the same answer regardless of the order in which you evaluate subexpressions. The definitions you give are not strongly normalizing, because there is an evaluation order that don't terminate:
a
-->
dh 2 (proj₁ b)
-->
dh 2 (proj₁ (dh 3 (proj₁ a))
-->
dh 2 (proj₁ (dh 3 (proj₁ (dh 2 (proj₁ b)))))
In particular, Agda's JavaScript backend would generate code that doesn't terminate for a and b, because JavaScript is strictly evaluated.
Agda's termination checker checks for a subset of strongly normalizing programs: those that have only structural recursion. It looks at the number and order of constructors pattern-matched in function definitions to determine whether recursive calls use "smaller" arguments. a and b don't have any parameters, so the termination checker sees the nested call from a to a (via b) as being the same "size" as a itself.

Related

Two Coq Problems SOS: one is about IndProp, another has something to do with recursion, I guess

(* 4. Let oddn and evenn be the predicates that test whether a given number
is odd or even. Show that the sum of an odd number with an even number is odd. *)
Inductive oddn : nat -> Prop :=
| odd1 : oddn 1
| odd2 : forall n, oddn n -> oddn (S (S n)).
Inductive evenn : nat -> Prop :=
| even1 : evenn 0
| even2 : forall n, evenn n -> evenn (S (S n)).
Theorem odd_add : forall n m, oddn n -> evenn m -> oddn (n + m).
Proof. intros. destruct m.
+ Search add. rewrite <- plus_n_O. apply H.
+ destruct H.
++ simpl. apply odd2.
I don't know how can I prove this theorem, since I can not link oddn with evenn.
(* 6. We call a natural number good if the sum of all
its digits is divisible by 5. For example 122 is good
but 93 is not. Define a function count such that
(count n) returns the number of good numbers smaller than
or equal to n. Here we assume that 0 <= n < 10000.
Hint: You may find the "let ... in" struct useful. You may
directly use the div and modulo functions defined in the
standard library of Coq. *)
Definition isGood(n:nat) : bool :=
Fixpoint count (n : nat) : nat :=
match n with
| 0 => 1
| S n' => if isGood n then 1 + count n'
else count n'
end.
Compute count 15.
Example count_test1 : count 15 = 3.
Proof. reflexivity. Qed.
Example count_test2 : count 2005 = 401.
Proof. reflexivity. Qed.
For the second problem, I got stuck because the recursion I defined won't be accepted by Coq(non-decreasing?).
I just got stuck with these two problems, can anyone work them out?
If you want to define independently oddnand even, you may prove a lemma which relates these two predicates, like:
Remark R : forall n, (evenn n <-> oddn (S n)) /\
(oddn n <-> evenn (S n)).
(* proof by induction on n *)
Then, it's easy to apply this remark for solving your first exercise.
Please note that you may define even and odd in several other ways:
as mutually inductive predicates
with existential quantifiers
define even, then oddin function of even
...
I don't understand the problem with the second exercise.
A few days ago, we discussed about a function sum_digits you can use (with modulo) to define isGood.
Your function count looks OK, but quite inefficient (with Peano natural numbers).

Recursion in the calculus of construction

How to define a recursive function in the (pure) calculus of constructions? I do not see any fixpoint combinator there.
People in the CS stack exchange might be able to provide some more insight, but here is an attempt.
Inductive data types are defined in the calculus of constructions with a Church encoding: the data type is the type of its fold function. The most basic example are the natural numbers, which are defined as follows, using a Coq-like notation:
nat := forall (T : Type), T -> (T -> T) -> T
This encoding yields two things: (1) terms zero : nat and succ : nat -> nat for constructing natural numbers, and (2) an operator nat_rec for writing recursive functions.
zero : nat
zero T x f := x
succ : nat -> nat
succ n T x f := f (n T x f)
nat_rec : forall T, T -> (T -> T) -> nat -> T
nat_rec T x f n := n T x f
If we pose F := nat_rec T x f for terms x : T and f : T -> T, we see that the following equations are valid:
F zero = x
F (succ n) = f (F n)
Thus, nat_rec allows us to define recursive functions by specifying a return value x for the base case, and a function f to process the value of the recursive call. Note that this does not allow us to define arbitrary recursive functions on the natural numbers, but only those that perform recursive calls on the predecessor of their argument. Allowing arbitrary recursion would open the door to partial functions, which would compromise the soundness of the calculus.
This example can be generalized to other inductive data types. For instance, we can define the type of lists of natural numbers as the type of their fold right function:
list_nat := forall T, T -> (nat -> T -> T) -> T

Agda Programming- Proving Insertionsort makes 3 or less comparisons on a list of size 3

Good Evening Fellows,
I am attempting to prove that insertionsort will perform <= 3 comparisons in a list of size 3 while sorting. Last part of my project and cannot make any headway on it. After spending fair amount of time pursuing an incorrect approach, my instructor informed me it may be accomplished by writing a helper function to assist. I unfortunately have not come up with any piece of code to help. If anyone can offer advice or assistance, any and all are appreciated. Code follows. Thanks!
insert : ℕ → 𝕃 ℕ → 𝕃 ℕ × ℕ
insert x (h :: t) = if h < x then (x :: h :: t , 1) else let r = insert
x t in h :: (fst r) , 1 + snd r
insert x [] = x :: [] , 0
insertionsort : 𝕃 ℕ → 𝕃 ℕ × ℕ
insertionsort [] = [] , 0
insertionsort (h :: t) with insertionsort t
insertionsort (h :: t) | t' , c1 with insert h t'
insertionsort (h :: t) | t' , c1 | r , c2 = r , c1 + c2
exampleThm : ∀(x y z c : ℕ)(r : 𝕃 ℕ) → insertionsort (x :: y :: z :: [])
≡ r , c → c ≤ 3 ≡ tt
exampleThm x y z = ?`
All the comparisons to be done in the course of insertionsort are actually done in the course of subordinate calls to insert. It may help to establish a useful fact about the comparison cost of insert. If you can bound the cost of each call to insert, you should be able to combine those bounded partial costs together to make a bounded total cost. In case your instructor is concerned that I am helping too much, let me summarize by saying that all I am saying is that the structure of the proof has to follow the structure of the program.
A general pattern when constructing proofs is to generalize them to make them easier. In this case I believe it is more clear to solve the generalized bound for the number of comparisons that insertion sort will do and then instantiate that to your particular input.
The structure of your proof will follow the structure of your program.
First we'll need to characterize the behavior of insert, since insertion sort is implemented in terms of it.
insert-bound : ∀ x ys → proj₂ (insert x ys) ≤ length ys
Then we'll use that to characterize the behavior of insertion sort
bound : ℕ → ℕ
bound 0 = 0
bound (suc n) = bound n + n
insertionsort-bound : ∀ xs → proj₂ (insertionsort xs) ≤ bound (length xs)
Using the general solution we can solve the specific case of a three element list
exampleThm : ∀ x y z c r → insertionsort (x ∷ y ∷ z ∷ []) ≡ (r , c) → c ≤ 3
exampleThm x y z ._ ._ refl = insertionsort-bound (x ∷ y ∷ z ∷ [])
Here's an implementation against the Agda standard library of your problem:
http://www.galois.com/~emertens/insertionsort-agda/Insertionsort.html

explain a simple operation in coq

I have the following code,
Here O is the charater O not zero 0
Module Playground1.
Inductive nat : Type :=
| O : nat
| S : nat → nat.
Definition pred (n : nat) : nat :=
match n with
| O ⇒ O
| S n' ⇒ n'
end.
End Playground1.
Definition minustwo (n : nat) : nat :=
match n with
| O ⇒ O
| S O ⇒ O
| S (S n') ⇒ n'
end.
Check (S (S (S (S O)))).
Eval compute in (minustwo 4).
I just want to know how it evaluates to 2? I mean how it is actually checking with a numeral and subtracting? I am not subtracting anything here, still it is working? I want to know what is the basic idea here? When I call minustwo 4 how coq know it is a numeral and how it is returning the result? How the matching is working here?
It is quite easy with Coq to follow step by step what is going on. But before we can do that, we need to know what your program looks like to Coq without all the syntactic sugar. To do that, type the following in your program:
Set Printing All.
If you now print minustwo, you will see that
Print minustwo
> match n return nat with
> | O => O
> | S n0 => match n0 return nat with
> | O => O
> | S n' => n'
> end
> end
your pattern match is actually broken up into two pattern matches.
Not let us see step by step how Coq evaluates minustwo 4. To do so, create the following theorem:
Goal (minustwo 4 = 2).
We don't care that much about the theorem itself, we care more about the fact that it contains the term minustwo 4. We can now simplify the expression step by step (you should run this in an ide to actually see what is going on).
First, we unfold the definition of minustwo, using a tactic called cbv delta.
cbv delta. (* unfold the definition of minustwo *)
We can now call the function, using the tactic cbv beta.
cbv beta. (* do the function call *)
We can now do the pattern match with
cbv iota; cbv beta. (* pattern match *)
And because Coq broke up the match into two, we get to do it again
cbv iota; cbv beta. (* pattern match *)
And that is why minustwo 4 is 2
reflexivity.
Qed.

coq --- function power definition

I am interested in how would one define f to the n in Coq:
Basically, as an exercise, I would like to write this definition and then confirm that my
algorithm implements this specification. Inductive definition seems appropriate here, but I was not able to make it clean as above. What would be a clean Coq implementation of the above?
With the pow_func function that gallais defined, you can state your specification as lemmas, such as:
Lemma pow_func0: forall (A:Type) (f: A -> A) (x: A), pow_fun f O x = f x.
and
Lemma pow_funcS: forall (n:nat) (A: Type) (f: A->A) (x:A), pow_fun f (S n) x = f (pow_fun f n x).
The proof should be trivial by unfolding the definition
Inductive is used to define types closed under some operations; this is not what you are looking for here. What you want to build is a recursive function iterating over n. This can be done using the Fixpoint keyword:
Fixpoint pow_func {A : Type} (f : A -> A) (n : nat) (a : A) : A :=
match n with
| O => f a
| S n => f (pow_func f n a)
end.
If you want a nicer syntax for this function, you can introduce a Notation:
Notation "f ^ n" := (pow_func f n).
However, note that this is not a well-behaved definition of a notion of power: if you compose f ^ m and f ^ n, you don't get f ^ (m + n) but rather f ^ (1 + m + n). To fix that, you should pick the base case f ^ 0 to be the neutral element for composition id rather than f itself. Which would give you:
Fixpoint pow_func' {A : Type} (f : A -> A) (n : nat) (a : A) : A :=
match n with
| O => a
| S n => f (pow_func' f n a)
end.

Resources