I have the following Inductive type defined in Coq.
Inductive natlist : Type :=
| nil : natlist
| cons : nat -> natlist -> natlist.
Notation "x :: l" := (cons x l) (at level 60, right associativity).
Notation "[ ]" := nil.
Notation "[ x , .. , y ]" := (cons x .. (cons y nil) ..).
The natlist is basically a list of natural numbers (similar to lists in Python). I am trying to find the union of two natlist using the definition below.
Definition union_of_lists : natlist -> natlist -> natlist
i.e
Eval simpl in (union_of_lists [1,2,3] [1,4,1])
should return [1,2,3,1,4,1]
I have the following doubts.
Since there are no arguments to this definition, how do I actually get the inputs and handle them?
What does the definition union_of_lists return exactly? Is it just a natlist?
Any help or hints are highly appreciated.
I found the answer myself :) What I did was, I wrote a separate Fixpoint function append and then assigned it to the definition of union_of_lists.
Fixpoint append(l1 l2 : natlist) : natlist :=
match l1 with
| nil => l2
| (h :: t) => h :: app t l2
end.`
and then
Definition union_of_lists : natlist -> natlist -> natlist := append.
Eval simpl in (append [1,2,3] [1,2,3]) (* returns [1,2,3,1,2,3] *)
The definition union_of_lists returns a function which takes natlist as an argument and returns another function of type natlist -> natlist (i.e function taking a natlist argument and returning a natlist).
This definition of union_of_lists resembles functions in Functional Programming which can either return a function or a value.
Related
My notation has been unintentionally unfolded after application.
I don't want to call the tactic 'change' on the last line in text of the tiny example every time I am using modus ponens.
How to forbid Coq to unfold my Notation "( a '==' b )"?
Require Export Coq.Vectors.Vector.
Import VectorNotations.
Inductive Terms : Type :=
FVC : nat -> Terms.
Definition Fo:=nat.
Context (axs0 : nat -> Type).
Context (Atom : Vector.t Terms 2 -> Fo).
Notation "( a '==' b )" := (Atom [a:Terms; b:Terms]).
Notation "( A --> B )" := (A + B).
Inductive GPR (axs : nat -> Type) (ctx:list nat) : nat -> Type :=
| MP (A B: Fo) : (GPR axs ctx A)->(GPR axs ctx (A --> B))
->(GPR axs ctx B).
Definition APR := GPR axs0.
Definition p2_23_a ctx (t:Terms) : APR ctx (t == t).
apply MP with (A:=(t == t)).
change (Atom [t; t]) with ((t==t)). (* <-- I don't want to write this line. *)
Change
Notation "( a '==' b )" := (Atom [a:Terms; b:Terms]).
to
Notation "( a '==' b )" := (Atom [a; b]).
Type annotations appear in the AST, and get easily simplified away, so the notation rarely matches.
Writing
Inductive Foo : Type -> Type :=
| foo : Foo Bar
with
Bar := .
gives
Error: Non strictly positive occurrence of "Bar" in "Foo Bar".
I know the standard example of why strict positivity is necessary; if I have
Inductive Fix :=
| fFix : (Fix -> Fix) -> Fix.
with an eliminator
Fix_rect : forall (P : Fix -> Type) (v : forall f, (forall x, P (f x)) -> P (fFix f)) (f : Fix), P f
then I can prove absurdity with
Fix_rect (fun _ => False) (fun f H => H (fFix id)) (fFix id) : False
(Aside: Does anything go wrong if instead the eliminator is
Fix_rect : forall (P : Fix -> Type) (v : forall f, (forall x, P x -> P (f x)) -> P (fFix f)) (f : Fix), P f
?)
However, I don't see a way to make use of occurrences that appear only in indices. Is there a way to derive a similar contradiction if non-strictly-positive occurrences are permitted in type indices?
This doesn't seem to be a positivity issue, contrary to the error message. Rather, since you have mutual indexing, this is an inductive-inductive type (a weird "large" one at that), which Coq doesn't support.
You could try defining non-indexed types, and separate recursively defined "well-formedness" relations which encode correct indexing. E. g.
Inductive PreFoo : Type :=
| foo : PreFoo.
Inductive Bar : Type :=.
Fixpoint FooWf (f : PreFoo) (t : Type) : Prop :=
match f with
| foo => (t = Bar)
end.
Definition Foo (t : Type) := sig (fun f => FooWf f t).
This is analogous to how you might have indexed intrinsic syntaxes for type theories or extrinsic presyntaxes with separate typing relations.
I am trying to proof an induction principle in Coq. Due to the definition of the data structure it is obligatory to show this principle via two nested inductions. The outer induction is done via the Fixpoint construct and the inner induction is done with principle list_ind.
The problem occuring is now that the induction argument of the inner induction is the result of a function, namely dfs t.
Inductive SearchTree (A : Type) : Type :=
| empty : SearchTree A
| leaf : A -> SearchTree A
| choice : SearchTree A -> SearchTree A -> SearchTree A.
Fixpoint dfs (A : Type) (t: SearchTree A) : list A :=
match t with
| empty => nil
| leaf x => cons x nil
| choice t1 t2 => app (dfs t1) (dfs t2)
end.
In the inner induction step I need to be able to apply the outer induction hypothesis to the first element of dfs t. But: when doing induction on dfs t this is not possible as it leads to an ill-formed recursion.
In my eyes the "normal" approach would be to do induction on t and simplification, but in case t = choice t1 t2 this always leads back to the initial problem as dfs (choice t1 t2) only reduces to dfs t1 ++ dfs t2.
Does somebody have an suggestion how to go on with this proof?
EDIT: Thought it might be a little much to show the code, but here it is:
Require Import Setoid.
Require Import Coq.Lists.List.
Set Implicit Arguments.
Set Contextual Implicit.
Section list.
Section listEquality.
Variable A : Type.
Variable eqA : A -> A -> Prop.
Inductive EqL : list A -> list A -> Prop :=
| EqL_nil : EqL nil nil
| EqL_cons : forall (x y : A) (xs ys : list A),
eqA x y ->
EqL xs ys ->
EqL (cons x xs) (cons y ys).
End listEquality.
End list.
Section SearchTree.
Inductive SearchTree (A : Type) : Type :=
| empty : SearchTree A
| leaf : A -> SearchTree A
| choice : SearchTree A -> SearchTree A -> SearchTree A.
Fixpoint dfs (A : Type) (t: SearchTree A) : list A :=
match t with
| empty => nil
| leaf x => cons x nil
| choice t1 t2 => app (dfs t1) (dfs t2)
end.
Section DFSEquality.
Variable A : Type.
Variable eqA : relation A.
Definition EqDFS (t1 t2: SearchTree A) : Prop :=
EqL eqA (dfs t1) (dfs t2).
End DFSEquality.
End SearchTree.
Section List.
Inductive List A :=
| Nil : List A
| Cons : SearchTree A -> SearchTree (List A) -> List A.
End List.
Section EqND.
Variable A : Type.
Variable eqA : relation A.
Inductive EqND : List A -> List A -> Prop :=
| Eq_Nil : EqND Nil Nil
| Eq_Cons : forall tx ty txs tys,
EqDFS eqA tx ty ->
EqDFS EqND txs tys ->
EqND (Cons tx txs) (Cons ty tys).
End EqND.
Section EqNDInd.
Variable A : Type.
Variable eqA : relation A.
Variable P : List A -> List A -> Prop.
Hypothesis BC : P Nil Nil.
Hypothesis ST: forall mx my mxs mys,
EqDFS eqA mx my
-> EqDFS (fun xs ys => EqND eqA xs ys /\ P xs ys) mxs mys
-> P (Cons mx mxs) (Cons my mys).
Fixpoint IND (xs ys : List A) { struct xs } : EqND eqA xs ys -> P xs ys.
Proof.
intro eq.
destruct xs,ys.
+ exact BC.
+ inversion eq.
+ inversion eq.
+ inversion eq. subst. apply ST.
++ exact H2.
++ unfold EqDFS in *.
generalize dependent (dfs s2).
induction (dfs s0).
+++ intros. inversion H4. constructor.
+++ intros. inversion H4. subst. constructor.
++++ split.
* exact H1.
* apply IND. exact H1. (* Guarded. *)
++++ clear IND. firstorder.
Admitted.
End EqNDInd.
The problem occurs proving IND, the Guarded. commented out fails.
To use nested recursion you have to resort to the raw fix construct using the "fix 1" tactic for example. The induction principles won't give you the right recursive calls. Beware that inversions might do rewritings that confuse the guard checker.
Actually, if you want the "nested" fixpoint to not be on a subterm of the original list but on [dfs t] then it's no longer a structural recursion and you need to justify the recursion using well-founded recursion. I have a similar example on rose trees where well-founded nested recursion is used.
There are two problems in your attempt:
The way you wrote IND prevent the recursive argument to be eq: EqND eqA xs ys, while this would be the natural one.
As remarked by #Matthieu Sozeau, the multiple inversions introduce noise.
Surprisingly, the proof is quite short.
Here is my solution:
Fixpoint IND (xs ys : List A) (eq: EqND eqA xs ys) : P xs ys.
Proof.
destruct eq.
- assumption.
- apply ST.
+ assumption.
+ unfold EqDFS in H0 |- *. induction H0.
* constructor.
* constructor.
-- split.
++ assumption.
++ apply IND. assumption.
-- assumption.
Qed.
I am writing a small program so that I can work some proofs of deMorgans laws using the type introduction/elimination rules from the HoTT book (et. al.). My model/example code is all here, https://mdnahas.github.io/doc/Reading_HoTT_in_Coq.pdf. So far I have,
Definition idmap {A:Type} (x:A) : A := x.
Inductive prod (A B:Type) : Type := pair : A -> B -> #prod A B.
Notation "x * y" := (prod x y) : type_scope.
Notation "x , y" := (pair _ _ x y) (at level 10).
Section projections.
Context {A : Type} {B : Type}.
Definition fst (p: A * B ) :=
match p with
| (x , y) => x
end.
Definition snd (p:A * B ) :=
match p with
| (x , y) => y
end.
End projections.
Inductive sum (A B : Type ) : Type :=
| inl : A -> sum A B
| inr : B -> sum A B.
Arguments inl {A B} _ , [A] B _.
Arguments inr {A B} _ , A [B].
Notation "x + y" := (sum x y) : type_scope.
Inductive Empty_set:Set :=.
Inductive unit:Set := tt:unit.
Definition Empty := Empty_set.
Definition Unit := unit.
Definition not (A:Type) : Type := A -> Empty.
Notation "~ x" := (not x) : type_scope.
Variables X:Type.
Variables Y:Type.
Goal (X * Y) -> (not X + not Y).
intro h. fst h.
Now I don't really know what the problem is. I've examples of people using definitions, but they always involve "Compute" commands, and I want to apply the rule fst to h to get x:X, so they are not helpful.
I tried "apply fst." which got me
Error: Cannot infer the implicit parameter B of fst whose type is
"Type" in environment:
h : A * B
In a proof context, Coq expects to get tactics to execute, not expressions to evaluate. Since fst is not defined as a tactic, it will give Error: The reference fst was not found in the current environment.
One possible tactic to execute along the lines of what you seem to be trying to do is set:
set (x := fst h).
I want to apply the rule fst to h to get x:X
I believe you can do
apply fst in h.
If you just write apply fst, Coq will apply the fst rule to the goal, rather than to h. If you write fst h, as Daniel says in his answer, Coq will attempt to run the fst tactic, which does not exist. In addition to Daniel's set solution, which will change the goal if fst h appears in it (and this may or may not be what you want), the following also work:
pose (fst h) as x. (* adds x := fst h to the context *)
pose proof (fst h) as x. (* adds opaque x : X to the context, justified by the term fst h *)
destruct h as [x y]. (* adds x : X and y : Y to the context, and replaces h with pair x y everywhere *)
I'm attempting to define and prove correct in Coq a function that efficiently diffs two sorted lists. As it does not always recurse on a structurally smaller term (either the first or second list is smaller), Fixpoint won't accept it, so I'm attempting to use Program Fixpoint instead.
When attempting to prove a property of the function using the tactic simpl or program_simpl, Coq spends minutes computing and then produces a giant term, hundreds of lines long. I was wondering if I'm using Program Fixpoint the wrong way, or alternatively if there are other tactics that should be used instead of simplification when reasoning about it?
I also wondered if it's good practice to include the required properties for correctness in params like this, or would it be better to have a separate wrapper function that takes the correctness properties as params, and make this function just take the two lists to be diffed?
Note that I did try defining a simpler version of make_diff, which only took l1 and l2 as parameters and fixed the type A and relation R, but this still produced a gigantic term when the program_simpl or simpl tactics were applied.
*Edit: my includes are (although they may not all be required here):
Require Import Coq.Sorting.Sorted.
Require Import Coq.Lists.List.
Require Import Coq.Relations.Relation_Definitions.
Require Import Recdef.
Require Import Coq.Program.Wf.
Require Import Coq.Program.Tactics.
The code:
Definition is_decidable (A : Type) (R : relation A) := forall x y, {R x y} + {~(R x y)}.
Definition eq_decidable (A : Type) := forall (x y : A), { x = y } + { ~ (x = y) }.
Inductive diff (X: Type) : Type :=
| add : X -> diff X
| remove : X -> diff X
| update : X -> X -> diff X.
Program Fixpoint make_diff (A : Type)
(R : relation A)
(dec : is_decidable A R)
(eq_dec : eq_decidable A)
(trans : transitive A R)
(lt_neq : (forall x y, R x y -> x <> y))
(l1 l2 : list A)
{measure (length l1 + length l2) } : list (diff A) :=
match l1, l2 with
| nil, nil => nil
| nil, (new_h::new_t) => (add A new_h) :: (make_diff A R dec eq_dec trans lt_neq nil new_t)
| (old_h::old_t), nil => (remove A old_h) :: (make_diff A R dec eq_dec trans lt_neq old_t nil)
| (old_h::old_t) as old_l, (new_h::new_t) as new_l =>
if dec old_h new_h
then (remove A old_h) :: make_diff A R dec eq_dec trans lt_neq old_t new_l
else if eq_dec old_h new_h
then (update A old_h new_h) :: make_diff A R dec eq_dec trans lt_neq old_t new_t
else (add A new_h) :: make_diff A R dec eq_dec trans lt_neq old_l new_t
end.
Next Obligation.
Proof.
simpl.
generalize dependent (length new_t).
generalize dependent (length old_t).
auto with arith.
Defined.
Next Obligation.
Proof.
simpl.
generalize dependent (length new_t).
generalize dependent (length old_t).
auto with arith.
Defined.
In this particular case we can get rid of Program Fixpoint and use plain simple Fixpoint. Since at each recursive call we invoke make_diff either on the tail of the first list or on the tail of the second list, we can nest two fixed-point functions as follows. (I have used the Section mechanism here to avoid passing too many identical arguments)
Require Import Coq.Lists.List.
Import ListNotations.
Require Import Coq.Relations.Relations.
Section Make_diff.
Variable A : Type.
Variable R : relation A.
Variable dec : is_decidable A R.
Variable eq_dec : eq_decidable A.
Variable trans : transitive A R.
Variable lt_neq : forall x y, R x y -> x <> y.
Fixpoint make_diff (l1 l2 : list A) : list (diff A) :=
let fix make_diff2 l2 :=
match l1, l2 with
| nil, nil => nil
| nil, new_h::new_t => (add A new_h) :: make_diff2 new_t
| old_h::old_t, nil => (remove A old_h) :: make_diff old_t nil
| old_h::old_t, new_h::new_t =>
if dec old_h new_h
then (remove A old_h) :: make_diff old_t l2
else if eq_dec old_h new_h
then (update A old_h new_h) :: make_diff old_t new_t
else (add A new_h) :: make_diff2 new_t
end
in make_diff2 l2.
End Make_diff.
Observe that the Section mechanism won't include unused parameters in the resulting signature. Here is a naive test:
(* make the first 2 arguments implicit *)
Arguments make_diff [A R] _ _ _ _.
Require Import Coq.Arith.Arith.
Compute make_diff lt_dec Nat.eq_dec [1;2;3] [4;5;6].
(* = [remove nat 1; remove nat 2; remove nat 3; add nat 4; add nat 5; add nat 6]
: list (diff nat) *)
For anyone who comes across the, a better alternative now is the Equations plugin, which will eventually replace Function and Program Fixpoint.