Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************)
(* * The Coq Proof Assistant / The Coq Development Team *)
(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
(* <O___,, * (see CREDITS file for the list of authors) *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
Decidability results about lists
Require Import List Decidable. Set Implicit Arguments. Definition decidable_eq A := forall x y:A, decidable (x=y). Section Dec_in_Prop. Variables (A:Type)(dec:decidable_eq A).A:Typedec:decidable_eq Ax:Al:list Adecidable (In x l)A:Typedec:decidable_eq Ax:Al:list Adecidable (In x l)A:Typedec:decidable_eq Ax:Adecidable (In x nil)A:Typedec:decidable_eq Ax, a:Al:list AIH:decidable (In x l)decidable (In x (a :: l))now right.A:Typedec:decidable_eq Ax:Adecidable (In x nil)A:Typedec:decidable_eq Ax, a:Al:list AIH:decidable (In x l)decidable (In x (a :: l))A:Typedec:decidable_eq Ax, a:Al:list AIH:decidable (In x l)H:a = xdecidable (In x (a :: l))A:Typedec:decidable_eq Ax, a:Al:list AIH:decidable (In x l)H:a <> xdecidable (In x (a :: l))A:Typedec:decidable_eq Ax, a:Al:list AIH:decidable (In x l)H:a = xdecidable (In x (a :: l))now left.A:Typedec:decidable_eq Ax, a:Al:list AIH:decidable (In x l)H:a = xIn x (a :: l)destruct IH; simpl; [left|right]; tauto. Qed.A:Typedec:decidable_eq Ax, a:Al:list AIH:decidable (In x l)H:a <> xdecidable (In x (a :: l))A:Typedec:decidable_eq Al, l':list Adecidable (incl l l')A:Typedec:decidable_eq Al, l':list Adecidable (incl l l')A:Typedec:decidable_eq Al':list Adecidable (incl nil l')A:Typedec:decidable_eq Aa:Al, l':list AIH:decidable (incl l l')decidable (incl (a :: l) l')A:Typedec:decidable_eq Al':list Adecidable (incl nil l')inversion 1.A:Typedec:decidable_eq Al':list Aincl nil l'A:Typedec:decidable_eq Aa:Al, l':list AIH:decidable (incl l l')decidable (incl (a :: l) l')A:Typedec:decidable_eq Aa:Al, l':list AIH:decidable (incl l l')IN:In a l'decidable (incl (a :: l) l')A:Typedec:decidable_eq Aa:Al, l':list AIH:decidable (incl l l')IN:~ In a l'decidable (incl (a :: l) l')A:Typedec:decidable_eq Aa:Al, l':list AIH:decidable (incl l l')IN:In a l'decidable (incl (a :: l) l')A:Typedec:decidable_eq Aa:Al, l':list AIC:incl l l'IN:In a l'decidable (incl (a :: l) l')A:Typedec:decidable_eq Aa:Al, l':list AIC:~ incl l l'IN:In a l'decidable (incl (a :: l) l')A:Typedec:decidable_eq Aa:Al, l':list AIC:incl l l'IN:In a l'decidable (incl (a :: l) l')destruct 1; subst; auto.A:Typedec:decidable_eq Aa:Al, l':list AIC:incl l l'IN:In a l'incl (a :: l) l'A:Typedec:decidable_eq Aa:Al, l':list AIC:~ incl l l'IN:In a l'decidable (incl (a :: l) l')A:Typedec:decidable_eq Aa:Al, l':list AIC:~ incl l l'IN:In a l'~ incl (a :: l) l'A:Typedec:decidable_eq Aa:Al, l':list AIN:In a l'IC:incl (a :: l) l'incl l l'apply IC; now right.A:Typedec:decidable_eq Aa:Al, l':list AIN:In a l'IC:incl (a :: l) l'x:AH:In x lIn x l'A:Typedec:decidable_eq Aa:Al, l':list AIH:decidable (incl l l')IN:~ In a l'decidable (incl (a :: l) l')A:Typedec:decidable_eq Aa:Al, l':list AIH:decidable (incl l l')IN:~ In a l'~ incl (a :: l) l'apply IN; now left. Qed.A:Typedec:decidable_eq Aa:Al, l':list AIH:decidable (incl l l')IN:incl (a :: l) l'In a l'A:Typedec:decidable_eq Al:list Adecidable (NoDup l)A:Typedec:decidable_eq Al:list Adecidable (NoDup l)A:Typedec:decidable_eq Adecidable (NoDup nil)A:Typedec:decidable_eq Aa:Al:list AIH:decidable (NoDup l)decidable (NoDup (a :: l))left; now constructor.A:Typedec:decidable_eq Adecidable (NoDup nil)A:Typedec:decidable_eq Aa:Al:list AIH:decidable (NoDup l)decidable (NoDup (a :: l))A:Typedec:decidable_eq Aa:Al:list AIH:decidable (NoDup l)H:In a ldecidable (NoDup (a :: l))A:Typedec:decidable_eq Aa:Al:list AIH:decidable (NoDup l)H:~ In a ldecidable (NoDup (a :: l))A:Typedec:decidable_eq Aa:Al:list AIH:decidable (NoDup l)H:In a ldecidable (NoDup (a :: l))A:Typedec:decidable_eq Aa:Al:list AIH:decidable (NoDup l)H:In a l~ NoDup (a :: l)tauto.A:Typedec:decidable_eq Aa:Al:list AIH:decidable (NoDup l)H:In a lH1:~ In a lH2:NoDup lFalseA:Typedec:decidable_eq Aa:Al:list AIH:decidable (NoDup l)H:~ In a ldecidable (NoDup (a :: l))A:Typedec:decidable_eq Aa:Al:list AH0:NoDup lH:~ In a ldecidable (NoDup (a :: l))A:Typedec:decidable_eq Aa:Al:list AH0:~ NoDup lH:~ In a ldecidable (NoDup (a :: l))A:Typedec:decidable_eq Aa:Al:list AH0:NoDup lH:~ In a ldecidable (NoDup (a :: l))now constructor.A:Typedec:decidable_eq Aa:Al:list AH0:NoDup lH:~ In a lNoDup (a :: l)A:Typedec:decidable_eq Aa:Al:list AH0:~ NoDup lH:~ In a ldecidable (NoDup (a :: l))A:Typedec:decidable_eq Aa:Al:list AH0:~ NoDup lH:~ In a l~ NoDup (a :: l)tauto. Qed. End Dec_in_Prop. Section Dec_in_Type. Variables (A:Type)(dec : forall x y:A, {x=y}+{x<>y}). Definition In_dec := List.In_dec dec. (* Already in List.v *)A:Typedec:decidable_eq Aa:Al:list AH0:~ NoDup lH, H2:~ In a lH3:NoDup lFalseA:Typedec:forall x y : A, {x = y} + {x <> y}l, l':list A{incl l l'} + {~ incl l l'}A:Typedec:forall x y : A, {x = y} + {x <> y}l, l':list A{incl l l'} + {~ incl l l'}A:Typedec:forall x y : A, {x = y} + {x <> y}l':list A{incl nil l'} + {~ incl nil l'}A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al, l':list AIH:{incl l l'} + {~ incl l l'}{incl (a :: l) l'} + {~ incl (a :: l) l'}A:Typedec:forall x y : A, {x = y} + {x <> y}l':list A{incl nil l'} + {~ incl nil l'}inversion 1.A:Typedec:forall x y : A, {x = y} + {x <> y}l':list Aincl nil l'A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al, l':list AIH:{incl l l'} + {~ incl l l'}{incl (a :: l) l'} + {~ incl (a :: l) l'}A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al, l':list AIH:{incl l l'} + {~ incl l l'}IN:In a l'{incl (a :: l) l'} + {~ incl (a :: l) l'}A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al, l':list AIH:{incl l l'} + {~ incl l l'}IN:~ In a l'{incl (a :: l) l'} + {~ incl (a :: l) l'}A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al, l':list AIH:{incl l l'} + {~ incl l l'}IN:In a l'{incl (a :: l) l'} + {~ incl (a :: l) l'}A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al, l':list AIC:incl l l'IN:In a l'{incl (a :: l) l'} + {~ incl (a :: l) l'}A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al, l':list AIC:~ incl l l'IN:In a l'{incl (a :: l) l'} + {~ incl (a :: l) l'}A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al, l':list AIC:incl l l'IN:In a l'{incl (a :: l) l'} + {~ incl (a :: l) l'}destruct 1; subst; auto.A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al, l':list AIC:incl l l'IN:In a l'incl (a :: l) l'A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al, l':list AIC:~ incl l l'IN:In a l'{incl (a :: l) l'} + {~ incl (a :: l) l'}A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al, l':list AIC:~ incl l l'IN:In a l'~ incl (a :: l) l'A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al, l':list AIN:In a l'IC:incl (a :: l) l'incl l l'apply IC; now right.A:Typedec:forall x0 y : A, {x0 = y} + {x0 <> y}a:Al, l':list AIN:In a l'IC:incl (a :: l) l'x:AH:In x lIn x l'A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al, l':list AIH:{incl l l'} + {~ incl l l'}IN:~ In a l'{incl (a :: l) l'} + {~ incl (a :: l) l'}A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al, l':list AIH:{incl l l'} + {~ incl l l'}IN:~ In a l'~ incl (a :: l) l'apply IN; now left. Qed.A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al, l':list AIH:{incl l l'} + {~ incl l l'}IN:incl (a :: l) l'In a l'A:Typedec:forall x y : A, {x = y} + {x <> y}l:list A{NoDup l} + {~ NoDup l}A:Typedec:forall x y : A, {x = y} + {x <> y}l:list A{NoDup l} + {~ NoDup l}A:Typedec:forall x y : A, {x = y} + {x <> y}{NoDup nil} + {~ NoDup nil}A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al:list AIH:{NoDup l} + {~ NoDup l}{NoDup (a :: l)} + {~ NoDup (a :: l)}left; now constructor.A:Typedec:forall x y : A, {x = y} + {x <> y}{NoDup nil} + {~ NoDup nil}A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al:list AIH:{NoDup l} + {~ NoDup l}{NoDup (a :: l)} + {~ NoDup (a :: l)}A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al:list AIH:{NoDup l} + {~ NoDup l}i:In a l{NoDup (a :: l)} + {~ NoDup (a :: l)}A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al:list AIH:{NoDup l} + {~ NoDup l}n:~ In a l{NoDup (a :: l)} + {~ NoDup (a :: l)}A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al:list AIH:{NoDup l} + {~ NoDup l}i:In a l{NoDup (a :: l)} + {~ NoDup (a :: l)}A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al:list AIH:{NoDup l} + {~ NoDup l}i:In a l~ NoDup (a :: l)tauto.A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al:list AIH:{NoDup l} + {~ NoDup l}i:In a lH0:~ In a lH1:NoDup lFalseA:Typedec:forall x y : A, {x = y} + {x <> y}a:Al:list AIH:{NoDup l} + {~ NoDup l}n:~ In a l{NoDup (a :: l)} + {~ NoDup (a :: l)}A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al:list An0:NoDup ln:~ In a l{NoDup (a :: l)} + {~ NoDup (a :: l)}A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al:list An0:~ NoDup ln:~ In a l{NoDup (a :: l)} + {~ NoDup (a :: l)}A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al:list An0:NoDup ln:~ In a l{NoDup (a :: l)} + {~ NoDup (a :: l)}now constructor.A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al:list An0:NoDup ln:~ In a lNoDup (a :: l)A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al:list An0:~ NoDup ln:~ In a l{NoDup (a :: l)} + {~ NoDup (a :: l)}A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al:list An0:~ NoDup ln:~ In a l~ NoDup (a :: l)tauto. Qed. End Dec_in_Type.A:Typedec:forall x y : A, {x = y} + {x <> y}a:Al:list An0:~ NoDup ln, H0:~ In a lH1:NoDup lFalse
An extra result: thanks to decidability, a list can be purged
from redundancies.
A, B:Typed:decidable_eq Bf:A -> Bl:list Aexists l' : list A, NoDup (map f l') /\ incl (map f l) (map f l')A, B:Typed:decidable_eq Bf:A -> Bl:list Aexists l' : list A, NoDup (map f l') /\ incl (map f l) (map f l')A, B:Typed:decidable_eq Bf:A -> Bexists l' : list A, NoDup (map f l') /\ incl (map f nil) (map f l')A, B:Typed:decidable_eq Bf:A -> Ba:Al:list AIHl:exists l' : list A, NoDup (map f l') /\ incl (map f l) (map f l')exists l' : list A, NoDup (map f l') /\ incl (map f (a :: l)) (map f l')A, B:Typed:decidable_eq Bf:A -> Bexists l' : list A, NoDup (map f l') /\ incl (map f nil) (map f l')A, B:Typed:decidable_eq Bf:A -> BNoDup (map f nil) /\ incl (map f nil) (map f nil)split; [now constructor | red; trivial].A, B:Typed:decidable_eq Bf:A -> BNoDup nil /\ incl nil nilA, B:Typed:decidable_eq Bf:A -> Ba:Al:list AIHl:exists l' : list A, NoDup (map f l') /\ incl (map f l) (map f l')exists l' : list A, NoDup (map f l') /\ incl (map f (a :: l)) (map f l')A, B:Typed:decidable_eq Bf:A -> Ba:Al, l':list AN:NoDup (map f l')I:incl (map f l) (map f l')exists l'0 : list A, NoDup (map f l'0) /\ incl (map f (a :: l)) (map f l'0)A, B:Typed:decidable_eq Bf:A -> Ba:Al, l':list AN:NoDup (map f l')I:incl (map f l) (map f l')H:In (f a) (map f l')exists l'0 : list A, NoDup (map f l'0) /\ incl (map f (a :: l)) (map f l'0)A, B:Typed:decidable_eq Bf:A -> Ba:Al, l':list AN:NoDup (map f l')I:incl (map f l) (map f l')H:~ In (f a) (map f l')exists l'0 : list A, NoDup (map f l'0) /\ incl (map f (a :: l)) (map f l'0)A, B:Typed:decidable_eq Bf:A -> Ba:Al, l':list AN:NoDup (map f l')I:incl (map f l) (map f l')H:In (f a) (map f l')exists l'0 : list A, NoDup (map f l'0) /\ incl (map f (a :: l)) (map f l'0)A, B:Typed:decidable_eq Bf:A -> Ba:Al, l':list AN:NoDup (map f l')I:incl (map f l) (map f l')H:In (f a) (map f l')incl (f a :: map f l) (map f l')A, B:Typed:decidable_eq Bf:A -> Ba:Al, l':list AN:NoDup (map f l')I:incl (map f l) (map f l')H:In (f a) (map f l')x:BHx:f a = xIn x (map f l')A, B:Typed:decidable_eq Bf:A -> Ba:Al, l':list AN:NoDup (map f l')I:incl (map f l) (map f l')H:In (f a) (map f l')x:BHx:In x (map f l)In x (map f l')now apply I.A, B:Typed:decidable_eq Bf:A -> Ba:Al, l':list AN:NoDup (map f l')I:incl (map f l) (map f l')H:In (f a) (map f l')x:BHx:In x (map f l)In x (map f l')A, B:Typed:decidable_eq Bf:A -> Ba:Al, l':list AN:NoDup (map f l')I:incl (map f l) (map f l')H:~ In (f a) (map f l')exists l'0 : list A, NoDup (map f l'0) /\ incl (map f (a :: l)) (map f l'0)A, B:Typed:decidable_eq Bf:A -> Ba:Al, l':list AN:NoDup (map f l')I:incl (map f l) (map f l')H:~ In (f a) (map f l')NoDup (f a :: map f l')A, B:Typed:decidable_eq Bf:A -> Ba:Al, l':list AN:NoDup (map f l')I:incl (map f l) (map f l')H:~ In (f a) (map f l')incl (f a :: map f l) (f a :: map f l')now constructor.A, B:Typed:decidable_eq Bf:A -> Ba:Al, l':list AN:NoDup (map f l')I:incl (map f l) (map f l')H:~ In (f a) (map f l')NoDup (f a :: map f l')A, B:Typed:decidable_eq Bf:A -> Ba:Al, l':list AN:NoDup (map f l')I:incl (map f l) (map f l')H:~ In (f a) (map f l')incl (f a :: map f l) (f a :: map f l')A, B:Typed:decidable_eq Bf:A -> Ba:Al, l':list AN:NoDup (map f l')I:incl (map f l) (map f l')H:~ In (f a) (map f l')x:BHx:f a = xIn x (f a :: map f l')A, B:Typed:decidable_eq Bf:A -> Ba:Al, l':list AN:NoDup (map f l')I:incl (map f l) (map f l')H:~ In (f a) (map f l')x:BHx:In x (map f l)In x (f a :: map f l')right; now apply I. Qed.A, B:Typed:decidable_eq Bf:A -> Ba:Al, l':list AN:NoDup (map f l')I:incl (map f l) (map f l')H:~ In (f a) (map f l')x:BHx:In x (map f l)In x (f a :: map f l')A:Typed:decidable_eq Al:list Aexists l' : list A, NoDup l' /\ incl l l'A:Typed:decidable_eq Al:list Aexists l' : list A, NoDup l' /\ incl l l'A:Typed:decidable_eq Al, l':list AH:NoDup (map id l') /\ incl (map id l) (map id l')exists l'0 : list A, NoDup l'0 /\ incl l l'0now rewrite !map_id in H. Qed.A:Typed:decidable_eq Al, l':list AH:NoDup (map id l') /\ incl (map id l) (map id l')NoDup l' /\ incl l l'