What does "==>" mean in coq? - coq

I have the following code:
Here is the def of sorted:
Fixpoint sorted (l : list nat) :=
match l with
| [] => true
| x::xs => match xs with
| [] => true
| y :: ys => (x <=? y) && (sorted xs)
end
end.
Here is the def of insert:
Fixpoint insert (x : nat) (l : list nat) :=
match l with
| [] => [x]
| y::ys => if x <=? y then x :: l
else y :: insert x ys
end.
Here is the def of insert_spec:
Definition insert_spec (x : nat) (l : list nat) :=
sorted l ==> sorted (insert x l).
In insert_spec, what does "==>" mean?

It appears that you got the code from Software Foundations' QuickChick guide. Many (if not all) of the notations used in that guide can be found in the QuickChick Reference Manual. There, we find that "==>" is defined as a notation.
Module QcNotation.
Export QcDefaultNotation.
Notation "x ==> y" :=
(implication x y) (at level 55, right associativity)
: Checker_scope.
End QcNotation.
implication is a generic "is this implication true" parameter used by QuickChick.
Parameter implication :
∀ {prop : Type} `{Checkable prop} (b : bool) (p : prop), Checker.
Whenever the first argument is true, QuickChick tests that the second argument evaluates (in whatever context you're using QuickChick in) as true too.
So for your particular piece of code, "==>" is used to say that we want to test that whenever l is sorted, insert x l is sorted too.

Related

Coq: Comparing an Int to a Nat in Separation Logic Foundations

Going through Separation Logic Foundations and I'm stuck on the exercise triple_mlength in Repr.v. I think my current problem is that I don't know how to handle ints and nats in Coq.
Lemma triple_mlength: forall (L: list val) (p:loc),
triple (mlength p)
(MList L p)
(fun r => \[r = val_int (length L)] \* (MList L p))
Check (fun L => val_int (length L)) doesn't throw an error, so that means length is capable of being an int. However, length is opaque and I can't unfold it.
My current context and goal:
x : val
p : loc
C : p <> null
x0 : loc
H : p <> null
xs : list val
IH : forall y : list val,
list_sub y (x :: xs) ->
forall p, triple (mlength p)
(MList y p)
(fun r:val => \[r = length y] \* MList y p)
______________________________________________________________
length xs + 1 = length (x :: xs)
Unsetting print notation the goal transforms into:
eq (Z.add (length xs) (Zpos xH)) (length (cons x xs))
which I think is trying to add (1:Z) to (length xs: nat), then compare it to (length (cons x xs) : nat)
Types:
Inductive nat : Set := O : nat
| S : nat -> nat
Inductive Z : Set := Z0 : int
| Zpos : positive -> int
| Zneg : positive -> int
list: forall A, list A -> nat
length: forall A, list A -> nat
val_int: int -> val
Coq version is 8.12.2
There is a coercion nat_to_Z : nat -> int in scope that is converting length xs : nat and length (x :: xs) : nat to ints. This is separate from the notation mechanism and thus you don't see it when you only ask Coq to show notations. However, it is there and you need to handle it in your proofs. There are a bunch of lemmas floating around that prove equivalence between nat operations and Z/int operations.
Having loaded your file and looked around a bit (Search is your friend!), it appears the reason you cannot simplify length (x :: xs) = S (length xs) is because there is a lemma length_cons which gives length (x :: xs) = (1 + length xs)%nat, instead. I suppose the authors of this book thought that would be a good idea for some reason, so they disabled the usual simplification. Do note that "normally" length is transparent and simpl would work on this goal.
After using length_cons, you can use plus_nat_eq_plus_int to push the coercion down under the +, and then Z.add_comm finishes. This line should satisfy the goal.
now rewrite length_cons, plus_nat_eq_plus_int, Z.add_comm.

How to express inheritance in Coq?

How can I get the all parents of a element in Coq?
I define a set in Coq as follows:
Inductive Gen : Set :=
| BGen : nat -> nat -> Gen.
There are many instances such as:
Definition g1 = BGen 1 2.
Definition g2 = BGen 2 3.
Now, I want to get the parents element of 3, i.e. [1,2]. I write a function:
Fixpoint parents (c : nat) (l : list Gen) :=
match l with
| [] => []
| (BGen p c') :: l' => if beq_nat c c'
then [p]
else parents c l'
end.
I can only get the direct parent [2] of 3, How can I get the all parents such as [1,2] in this example?
You seem to be asking about how to compute the closure of a function under repeated function application. The key to the problem is to find a way to ensure termination, i.e., a way to determine the maximum number of times the function might be called. In this case, an easy upper bound is List.length l; an element cannot have more transitive-parents than there are generations. Using this insight, we can define a function that takes a list of numbers, and outputs a list of those numbers together with all of their parents, and then we apply this function List.length l times to itself, starting with parents of c:
Require Import Coq.Lists.List. Import ListNotations.
Require Import Coq.Sorting.Mergesort. Import NatSort.
Scheme Equality for nat.
Inductive Gen : Set :=
| BGen : nat -> nat -> Gen.
Definition g1 := BGen 1 2.
Definition g2 := BGen 2 3.
Fixpoint parents (l : list Gen) (c : nat) :=
match l with
| [] => []
| (BGen p c') :: l' => if nat_beq c c'
then [p]
else parents l' c
end.
Fixpoint deduplicate' (ls : list nat) :=
match ls with
| [] => []
| x :: [] => [x]
| x :: ((y :: ys) as xs)
=> if nat_beq x y
then deduplicate' xs
else x :: deduplicate' xs
end.
Definition deduplicate (ls : list nat) := deduplicate' (sort ls).
Definition parents_step (l : list Gen) (cs : list nat) :=
deduplicate (cs ++ List.flat_map (parents l) cs).
Fixpoint all_parents' (l : list Gen) (cs : list nat) (fuel : nat) :=
match fuel with
| 0 => cs
| S fuel'
=> all_parents' l (parents_step l cs) fuel'
end.
Definition all_parents (l : list Gen) (c : nat) :=
deduplicate (all_parents' l (parents l c) (List.length l)).
Definition gs := (g1::g2::nil).
Compute all_parents gs 3. (* [1; 2] *)

Coq polymorphic function without explicit type

I have an "enumerate" function written in the Coq term language (what is it called?). This function is kind of annoying to use because it requires that A (the type of an element in the list l) be explicitly provided whenever the enumerate function is used. Is there a way to avoid needing to explicitly pass A as a parameter?
(* [a, b] -> [(0,a), (1,b)] *)
Fixpoint enumerate (A : Type) (l : list A) : list (nat * A) :=
let empty : (list (nat * A)) := nil in
let incr_pair xy := match xy with
| (x, y) => ((S x), y)
end in
match l with
| nil => empty
| (x :: xs) => (O, x) :: (map incr_pair (enumerate A xs))
end.
I want to be able to write something like
Fixpoint enumerate (l : list A) : list (nat * A) := ...
Possibly with some additional syntax identifying what exactly A is.
Put arguments in brackets to make them implicit by default (see section 2.7.4 here). Also, you should probably write this function in a non-quadratic way with a nat accumulator.
Require Import Lists.List.
Import ListNotations.
Fixpoint enumerate_from {A : Type} (n : nat) (l : list A) : list (nat * A) :=
match l with
| [] => []
| x :: xs => (n, x) :: enumerate_from (S n) xs
end.
Definition enumerate {A} l : list (nat * A) := enumerate_from 0 l.
Compute (enumerate [3; 4; 5]). (* prints [(0, 3); (1, 4); (2, 5)] *)

When is the first input to `list_rec` not a constant function?

The list_rec function has the type:
list_rec
: forall (A : Type) (P : list A -> Set),
P nil ->
(forall (a : A) (l : list A), P l -> P (a :: l)%list) ->
forall l : list A, P l
In all of the examples I've come up with, P is just a constant function that ignores the input list and returns the same type no matter what. For example, P might be fun _ : list A => nat or fun _ : list A => list B. What are some use cases for making the output of P dependent on the input? Why is the type of P list A -> Set instead of just Set?
We can, for example, use list_rec with a non-constant P function to implement a function that converts a list to a vector (a length-indexed list).
Require List Vector.
Import List.ListNotations Vector.VectorNotations.
Set Implicit Arguments.
Section VecExample.
Variable A : Set.
Definition P (xs : list A) : Set := Vector.t A (length xs).
Definition list_to_vector : forall xs : list A, Vector.t A (length xs) :=
list_rec P [] (fun x _ vtail => x :: vtail).
End VecExample.
You can compare it with the standard definition of the Vector.of_list function, which does exactly the same (t means Vector.t in the following code), using explicit recursion instead of hiding it behind a recursion principle:
Fixpoint of_list {A} (l : list A) : t A (length l) :=
match l as l' return t A (length l') with
|Datatypes.nil => []
|(h :: tail)%list => (h :: (of_list tail))
end.
A simple test:
Eval compute in list_to_vector [1;2;3].
Eval compute in Vector.of_list [1;2;3].
Both function calls return the same result:
= [1; 2; 3]
: Vector.t nat (length [1; 2; 3])
Try to prove s ++ [] = s.
[Hint: Define P as fun s => s ++ [] = s.]

Restating lambdas in Coq without extensional function equality?

I am going over Software Foundations. There are two definitions of list reverse function given.
Fixpoint rev (l:natlist) : natlist :=
match l with
| nil => nil
| h :: t => rev t ++ [h]
end.
and a tail-recursive one:
Fixpoint rev_append {X} (l1 l2 : list X) : list X :=
match l1 with
| [] => l2
| x :: l1' => rev_append l1' (x :: l2)
end.
Definition tr_rev {X} (l : list X) : list X :=
rev_append l [].
Here is where the problem arrives. I am asked to prove their equality, with the following theorem stated: Lemma tr_rev_correct : ∀X, #tr_rev X = #rev X.
This generates the following proof state:
1 subgoal
______________________________________(1/1)
forall X : Type, tr_rev = rev
However, even if I do unfold tr_rev (and / or the other two definitions), I end up with something along the lines of:
1 subgoal
______________________________________(1/1)
forall X : Type, (fun l : list X => rev_append l [ ]) = rev
But I can't do anything with this formulation (other than intro X).
What I would like to have is this:
Lemma tr_rev_correct : forall (X : Type) (l : list X), tr_rev l = rev l.
Is there a way to replace the former with the latter without involving functional extensionality? (If I didn't want to restate the lemma that is given by the book.)