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) *)
(************************************************************************)
Authors: Bruno Barras, Cristina Cornes
Require Import Eqdep. Require Import Relation_Operators. Require Import Transitive_Closure.
From : Constructing Recursion Operators in Type Theory
L. Paulson JSC (1986) 2, 325-355
Section WfLexicographic_Product. Variable A : Type. Variable B : A -> Type. Variable leA : A -> A -> Prop. Variable leB : forall x:A, B x -> B x -> Prop. Notation LexProd := (lexprod A B leA leB).A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x : A, B x -> B x -> Propforall x : A, Acc leA x -> (forall x0 : A, clos_trans A leA x0 x -> well_founded (leB x0)) -> forall y : B x, Acc (leB x) y -> Acc LexProd (existT B x y)A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x : A, B x -> B x -> Propforall x : A, Acc leA x -> (forall x0 : A, clos_trans A leA x0 x -> well_founded (leB x0)) -> forall y : B x, Acc (leB x) y -> Acc LexProd (existT B x y)A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x0 : A, B x0 -> B x0 -> Propx:AIHAcc:forall y0 : A, leA y0 x -> (forall x0 : A, clos_trans A leA x0 y0 -> well_founded (leB x0)) -> forall y1 : B y0, Acc (leB y0) y1 -> Acc LexProd (existT B y0 y1)H2:forall x0 : A, clos_trans A leA x0 x -> well_founded (leB x0)y:B xAcc (leB x) y -> Acc LexProd (existT B x y)A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x1 : A, B x1 -> B x1 -> Propx:AIHAcc:forall y : A, leA y x -> (forall x1 : A, clos_trans A leA x1 y -> well_founded (leB x1)) -> forall y0 : B y, Acc (leB y) y0 -> Acc LexProd (existT B y y0)H2:forall x1 : A, clos_trans A leA x1 x -> well_founded (leB x1)x0:B xH:forall y : B x, leB x y x0 -> Acc (leB x) yIHAcc0:forall y : B x, leB x y x0 -> Acc LexProd (existT B x y)Acc LexProd (existT B x x0)A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x1 : A, B x1 -> B x1 -> Propx:AIHAcc:forall y : A, leA y x -> (forall x1 : A, clos_trans A leA x1 y -> well_founded (leB x1)) -> forall y0 : B y, Acc (leB y) y0 -> Acc LexProd (existT B y y0)H2:forall x1 : A, clos_trans A leA x1 x -> well_founded (leB x1)x0:B xH:forall y : B x, leB x y x0 -> Acc (leB x) yIHAcc0:forall y : B x, leB x y x0 -> Acc LexProd (existT B x y)forall y : {x : A & B x}, LexProd y (existT B x x0) -> Acc LexProd yA:TypeB:A -> TypeleA:A -> A -> PropleB:forall x1 : A, B x1 -> B x1 -> Propx:AIHAcc:forall y : A, leA y x -> (forall x1 : A, clos_trans A leA x1 y -> well_founded (leB x1)) -> forall y0 : B y, Acc (leB y) y0 -> Acc LexProd (existT B y y0)H2:forall x1 : A, clos_trans A leA x1 x -> well_founded (leB x1)x0:B xH:forall y : B x, leB x y x0 -> Acc (leB x) yIHAcc0:forall y : B x, leB x y x0 -> Acc LexProd (existT B x y)x2:Ay1:B x2H6:LexProd (existT B x2 y1) (existT B x x0)Acc LexProd (existT B x2 y1)A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x3 : A, B x3 -> B x3 -> Propx:AIHAcc:forall y0 : A, leA y0 x -> (forall x3 : A, clos_trans A leA x3 y0 -> well_founded (leB x3)) -> forall y2 : B y0, Acc (leB y0) y2 -> Acc LexProd (existT B y0 y2)H2:forall x3 : A, clos_trans A leA x3 x -> well_founded (leB x3)x0:B xH:forall y0 : B x, leB x y0 x0 -> Acc (leB x) y0IHAcc0:forall y0 : B x, leB x y0 x0 -> Acc LexProd (existT B x y0)x2:Ay1:B x2H6:LexProd (existT B x2 y1) (existT B x x0)x1, x':Ay:B x1y':B x'H1:existT B x1 y = existT B x2 y1H3:existT B x' y' = existT B x x0H0:leA x1 x'Acc LexProd (existT B x2 y1)A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x3 : A, B x3 -> B x3 -> Propx:AIHAcc:forall y0 : A, leA y0 x -> (forall x3 : A, clos_trans A leA x3 y0 -> well_founded (leB x3)) -> forall y2 : B y0, Acc (leB y0) y2 -> Acc LexProd (existT B y0 y2)H2:forall x3 : A, clos_trans A leA x3 x -> well_founded (leB x3)x0:B xH:forall y0 : B x, leB x y0 x0 -> Acc (leB x) y0IHAcc0:forall y0 : B x, leB x y0 x0 -> Acc LexProd (existT B x y0)x2:Ay1:B x2H6:LexProd (existT B x2 y1) (existT B x x0)x1:Ay, y':B x1H1:existT B x1 y = existT B x2 y1H3:existT B x1 y' = existT B x x0H0:leB x1 y y'Acc LexProd (existT B x2 y1)A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x3 : A, B x3 -> B x3 -> Propx:AIHAcc:forall y0 : A, leA y0 x -> (forall x3 : A, clos_trans A leA x3 y0 -> well_founded (leB x3)) -> forall y2 : B y0, Acc (leB y0) y2 -> Acc LexProd (existT B y0 y2)H2:forall x3 : A, clos_trans A leA x3 x -> well_founded (leB x3)x0:B xH:forall y0 : B x, leB x y0 x0 -> Acc (leB x) y0IHAcc0:forall y0 : B x, leB x y0 x0 -> Acc LexProd (existT B x y0)x2:Ay1:B x2H6:LexProd (existT B x2 y1) (existT B x x0)x1, x':Ay:B x1y':B x'H1:existT B x1 y = existT B x2 y1H3:existT B x' y' = existT B x x0H0:leA x1 x'Acc LexProd (existT B x2 y1)A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x3 : A, B x3 -> B x3 -> Propx:AIHAcc:forall y0 : A, leA y0 x -> (forall x3 : A, clos_trans A leA x3 y0 -> well_founded (leB x3)) -> forall y2 : B y0, Acc (leB y0) y2 -> Acc LexProd (existT B y0 y2)H2:forall x3 : A, clos_trans A leA x3 x -> well_founded (leB x3)x0:B xH:forall y0 : B x, leB x y0 x0 -> Acc (leB x) y0IHAcc0:forall y0 : B x, leB x y0 x0 -> Acc LexProd (existT B x y0)x2:Ay1:B x2H6:LexProd (existT B x2 y1) (existT B x x0)x1, x':Ay:B x1y':B x'H1:existT B x1 y = existT B x2 y1H3:existT B x' y' = existT B x x0H0:leA x1 x'H4:leA x2 xAcc LexProd (existT B x2 y1)A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x3 : A, B x3 -> B x3 -> Propx:AIHAcc:forall y0 : A, leA y0 x -> (forall x3 : A, clos_trans A leA x3 y0 -> well_founded (leB x3)) -> forall y2 : B y0, Acc (leB y0) y2 -> Acc LexProd (existT B y0 y2)H2:forall x3 : A, clos_trans A leA x3 x -> well_founded (leB x3)x0:B xH:forall y0 : B x, leB x y0 x0 -> Acc (leB x) y0IHAcc0:forall y0 : B x, leB x y0 x0 -> Acc LexProd (existT B x y0)x2:Ay1:B x2H6:LexProd (existT B x2 y1) (existT B x x0)x1, x':Ay:B x1y':B x'H1:existT B x1 y = existT B x2 y1H3:existT B x' y' = existT B x x0H0:leA x1 x'leA x2 xA:TypeB:A -> TypeleA:A -> A -> PropleB:forall x3 : A, B x3 -> B x3 -> Propx:AIHAcc:forall y0 : A, leA y0 x -> (forall x3 : A, clos_trans A leA x3 y0 -> well_founded (leB x3)) -> forall y2 : B y0, Acc (leB y0) y2 -> Acc LexProd (existT B y0 y2)H2:forall x3 : A, clos_trans A leA x3 x -> well_founded (leB x3)x0:B xH:forall y0 : B x, leB x y0 x0 -> Acc (leB x) y0IHAcc0:forall y0 : B x, leB x y0 x0 -> Acc LexProd (existT B x y0)x2:Ay1:B x2H6:LexProd (existT B x2 y1) (existT B x x0)x1, x':Ay:B x1y':B x'H1:existT B x1 y = existT B x2 y1H3:existT B x' y' = existT B x x0H0:leA x1 x'H4:leA x2 xAcc LexProd (existT B x2 y1)A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x3 : A, B x3 -> B x3 -> Propx:AIHAcc:forall y0 : A, leA y0 x -> (forall x3 : A, clos_trans A leA x3 y0 -> well_founded (leB x3)) -> forall y2 : B y0, Acc (leB y0) y2 -> Acc LexProd (existT B y0 y2)H2:forall x3 : A, clos_trans A leA x3 x -> well_founded (leB x3)x0:B xH:forall y0 : B x, leB x y0 x0 -> Acc (leB x) y0IHAcc0:forall y0 : B x, leB x y0 x0 -> Acc LexProd (existT B x y0)x2:Ay1:B x2H6:LexProd (existT B x2 y1) (existT B x x0)x1, x':Ay:B x1y':B x'H1:existT B x1 y = existT B x2 y1H3:existT B x' y' = existT B x x0H0:leA x1 x'H4:leA x2 xforall x3 : A, clos_trans A leA x3 x2 -> well_founded (leB x3)A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x3 : A, B x3 -> B x3 -> Propx:AIHAcc:forall y0 : A, leA y0 x -> (forall x3 : A, clos_trans A leA x3 y0 -> well_founded (leB x3)) -> forall y2 : B y0, Acc (leB y0) y2 -> Acc LexProd (existT B y0 y2)H2:forall x3 : A, clos_trans A leA x3 x -> well_founded (leB x3)x0:B xH:forall y0 : B x, leB x y0 x0 -> Acc (leB x) y0IHAcc0:forall y0 : B x, leB x y0 x0 -> Acc LexProd (existT B x y0)x2:Ay1:B x2H6:LexProd (existT B x2 y1) (existT B x x0)x1, x':Ay:B x1y':B x'H1:existT B x1 y = existT B x2 y1H3:existT B x' y' = existT B x x0H0:leA x1 x'H4:leA x2 xAcc (leB x2) y1A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x3 : A, B x3 -> B x3 -> Propx:AIHAcc:forall y0 : A, leA y0 x -> (forall x3 : A, clos_trans A leA x3 y0 -> well_founded (leB x3)) -> forall y2 : B y0, Acc (leB y0) y2 -> Acc LexProd (existT B y0 y2)H2:forall x3 : A, clos_trans A leA x3 x -> well_founded (leB x3)x0:B xH:forall y0 : B x, leB x y0 x0 -> Acc (leB x) y0IHAcc0:forall y0 : B x, leB x y0 x0 -> Acc LexProd (existT B x y0)x2:Ay1:B x2H6:LexProd (existT B x2 y1) (existT B x x0)x1, x':Ay:B x1y':B x'H1:existT B x1 y = existT B x2 y1H3:existT B x' y' = existT B x x0H0:leA x1 x'H4:leA x2 xforall x3 : A, clos_trans A leA x3 x2 -> well_founded (leB x3)A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x4 : A, B x4 -> B x4 -> Propx:AIHAcc:forall y0 : A, leA y0 x -> (forall x4 : A, clos_trans A leA x4 y0 -> well_founded (leB x4)) -> forall y2 : B y0, Acc (leB y0) y2 -> Acc LexProd (existT B y0 y2)H2:forall x4 : A, clos_trans A leA x4 x -> well_founded (leB x4)x0:B xH:forall y0 : B x, leB x y0 x0 -> Acc (leB x) y0IHAcc0:forall y0 : B x, leB x y0 x0 -> Acc LexProd (existT B x y0)x2:Ay1:B x2H6:LexProd (existT B x2 y1) (existT B x x0)x1, x':Ay:B x1y':B x'H1:existT B x1 y = existT B x2 y1H3:existT B x' y' = existT B x x0H0:leA x1 x'H4:leA x2 xx3:AH5:clos_trans A leA x3 x2well_founded (leB x3)apply t_trans with x2; auto with sets.A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x4 : A, B x4 -> B x4 -> Propx:AIHAcc:forall y0 : A, leA y0 x -> (forall x4 : A, clos_trans A leA x4 y0 -> well_founded (leB x4)) -> forall y2 : B y0, Acc (leB y0) y2 -> Acc LexProd (existT B y0 y2)H2:forall x4 : A, clos_trans A leA x4 x -> well_founded (leB x4)x0:B xH:forall y0 : B x, leB x y0 x0 -> Acc (leB x) y0IHAcc0:forall y0 : B x, leB x y0 x0 -> Acc LexProd (existT B x y0)x2:Ay1:B x2H6:LexProd (existT B x2 y1) (existT B x x0)x1, x':Ay:B x1y':B x'H1:existT B x1 y = existT B x2 y1H3:existT B x' y' = existT B x x0H0:leA x1 x'H4:leA x2 xx3:AH5:clos_trans A leA x3 x2clos_trans A leA x3 xA:TypeB:A -> TypeleA:A -> A -> PropleB:forall x3 : A, B x3 -> B x3 -> Propx:AIHAcc:forall y0 : A, leA y0 x -> (forall x3 : A, clos_trans A leA x3 y0 -> well_founded (leB x3)) -> forall y2 : B y0, Acc (leB y0) y2 -> Acc LexProd (existT B y0 y2)H2:forall x3 : A, clos_trans A leA x3 x -> well_founded (leB x3)x0:B xH:forall y0 : B x, leB x y0 x0 -> Acc (leB x) y0IHAcc0:forall y0 : B x, leB x y0 x0 -> Acc LexProd (existT B x y0)x2:Ay1:B x2H6:LexProd (existT B x2 y1) (existT B x x0)x1, x':Ay:B x1y':B x'H1:existT B x1 y = existT B x2 y1H3:existT B x' y' = existT B x x0H0:leA x1 x'H4:leA x2 xAcc (leB x2) y1A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x3 : A, B x3 -> B x3 -> Propx:AIHAcc:forall y0 : A, leA y0 x -> (forall x3 : A, clos_trans A leA x3 y0 -> well_founded (leB x3)) -> forall y2 : B y0, Acc (leB y0) y2 -> Acc LexProd (existT B y0 y2)H2:forall x3 : A, clos_trans A leA x3 x -> forall a : B x3, Acc (leB x3) ax0:B xH:forall y0 : B x, leB x y0 x0 -> Acc (leB x) y0IHAcc0:forall y0 : B x, leB x y0 x0 -> Acc LexProd (existT B x y0)x2:Ay1:B x2H6:LexProd (existT B x2 y1) (existT B x x0)x1, x':Ay:B x1y':B x'H1:existT B x1 y = existT B x2 y1H3:existT B x' y' = existT B x x0H0:leA x1 x'H4:leA x2 xAcc (leB x2) y1auto with sets.A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x3 : A, B x3 -> B x3 -> Propx:AIHAcc:forall y0 : A, leA y0 x -> (forall x3 : A, clos_trans A leA x3 y0 -> well_founded (leB x3)) -> forall y2 : B y0, Acc (leB y0) y2 -> Acc LexProd (existT B y0 y2)H2:forall x3 : A, clos_trans A leA x3 x -> forall a : B x3, Acc (leB x3) ax0:B xH:forall y0 : B x, leB x y0 x0 -> Acc (leB x) y0IHAcc0:forall y0 : B x, leB x y0 x0 -> Acc LexProd (existT B x y0)x2:Ay1:B x2H6:LexProd (existT B x2 y1) (existT B x x0)x1, x':Ay:B x1y':B x'H1:existT B x1 y = existT B x2 y1H3:existT B x' y' = existT B x x0H0:leA x1 x'H4:leA x2 xclos_trans A leA x2 xA:TypeB:A -> TypeleA:A -> A -> PropleB:forall x3 : A, B x3 -> B x3 -> Propx:AIHAcc:forall y0 : A, leA y0 x -> (forall x3 : A, clos_trans A leA x3 y0 -> well_founded (leB x3)) -> forall y2 : B y0, Acc (leB y0) y2 -> Acc LexProd (existT B y0 y2)H2:forall x3 : A, clos_trans A leA x3 x -> well_founded (leB x3)x0:B xH:forall y0 : B x, leB x y0 x0 -> Acc (leB x) y0IHAcc0:forall y0 : B x, leB x y0 x0 -> Acc LexProd (existT B x y0)x2:Ay1:B x2H6:LexProd (existT B x2 y1) (existT B x x0)x1, x':Ay:B x1y':B x'H1:existT B x1 y = existT B x2 y1H3:existT B x' y' = existT B x x0H0:leA x1 x'leA x2 xinjection H3 as <- _; auto with sets.A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x2 : A, B x2 -> B x2 -> Propx:AIHAcc:forall y0 : A, leA y0 x -> (forall x2 : A, clos_trans A leA x2 y0 -> well_founded (leB x2)) -> forall y2 : B y0, Acc (leB y0) y2 -> Acc LexProd (existT B y0 y2)H2:forall x2 : A, clos_trans A leA x2 x -> well_founded (leB x2)x0:B xH:forall y0 : B x, leB x y0 x0 -> Acc (leB x) y0IHAcc0:forall y0 : B x, leB x y0 x0 -> Acc LexProd (existT B x y0)x1:Ay1:B x1H6:LexProd (existT B x1 y1) (existT B x x0)x':Ay:B x1y':B x'H3:existT B x' y' = existT B x x0H0:leA x1 x'leA x1 xA:TypeB:A -> TypeleA:A -> A -> PropleB:forall x3 : A, B x3 -> B x3 -> Propx:AIHAcc:forall y0 : A, leA y0 x -> (forall x3 : A, clos_trans A leA x3 y0 -> well_founded (leB x3)) -> forall y2 : B y0, Acc (leB y0) y2 -> Acc LexProd (existT B y0 y2)H2:forall x3 : A, clos_trans A leA x3 x -> well_founded (leB x3)x0:B xH:forall y0 : B x, leB x y0 x0 -> Acc (leB x) y0IHAcc0:forall y0 : B x, leB x y0 x0 -> Acc LexProd (existT B x y0)x2:Ay1:B x2H6:LexProd (existT B x2 y1) (existT B x x0)x1:Ay, y':B x1H1:existT B x1 y = existT B x2 y1H3:existT B x1 y' = existT B x x0H0:leB x1 y y'Acc LexProd (existT B x2 y1)A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x3 : A, B x3 -> B x3 -> Propx:AIHAcc:forall y0 : A, leA y0 x -> (forall x3 : A, clos_trans A leA x3 y0 -> well_founded (leB x3)) -> forall y2 : B y0, Acc (leB y0) y2 -> Acc LexProd (existT B y0 y2)H2:forall x3 : A, clos_trans A leA x3 x -> well_founded (leB x3)x0:B xH:forall y0 : B x, leB x y0 x0 -> Acc (leB x) y0IHAcc0:forall y0 : B x, leB x y0 x0 -> Acc LexProd (existT B x y0)x2:Ay1:B x2H6:LexProd (existT B x2 y1) (existT B x x0)x1:Ay, y':B x1H1:existT B x1 y = existT B x2 y1H3:existT B x1 y' = existT B x x0H0:leB x1 y y'Acc LexProd (existT B x1 y)A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x1 : A, B x1 -> B x1 -> Propx:AIHAcc:forall y0 : A, leA y0 x -> (forall x1 : A, clos_trans A leA x1 y0 -> well_founded (leB x1)) -> forall y2 : B y0, Acc (leB y0) y2 -> Acc LexProd (existT B y0 y2)H2:forall x1 : A, clos_trans A leA x1 x -> well_founded (leB x1)x0:B xH:forall y0 : B x, leB x y0 x0 -> Acc (leB x) y0IHAcc0:forall y0 : B x, leB x y0 x0 -> Acc LexProd (existT B x y0)x2:Ay1:B x2H6:LexProd (existT B x2 y1) (existT B x x0)y:B xH1:existT B x y = existT B x2 y1y':B xH3:existT (fun x1 : A => B x1) x y' = existT (fun x1 : A => B x1) x x0H0:leB x y y'Acc LexProd (existT B x y)elim inj_pair2 with A B x y' x0; assumption. Defined.A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x1 : A, B x1 -> B x1 -> Propx:AIHAcc:forall y0 : A, leA y0 x -> (forall x1 : A, clos_trans A leA x1 y0 -> well_founded (leB x1)) -> forall y2 : B y0, Acc (leB y0) y2 -> Acc LexProd (existT B y0 y2)H2:forall x1 : A, clos_trans A leA x1 x -> well_founded (leB x1)x0:B xH:forall y0 : B x, leB x y0 x0 -> Acc (leB x) y0IHAcc0:forall y0 : B x, leB x y0 x0 -> Acc LexProd (existT B x y0)x2:Ay1:B x2H6:LexProd (existT B x2 y1) (existT B x x0)y:B xH1:existT B x y = existT B x2 y1y':B xH3:existT (fun x1 : A => B x1) x y' = existT (fun x1 : A => B x1) x x0H0:leB x y y'leB x y x0A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x : A, B x -> B x -> Propwell_founded leA -> (forall x : A, well_founded (leB x)) -> well_founded LexProdA:TypeB:A -> TypeleA:A -> A -> PropleB:forall x : A, B x -> B x -> Propwell_founded leA -> (forall x : A, well_founded (leB x)) -> well_founded LexProdA:TypeB:A -> TypeleA:A -> A -> PropleB:forall x : A, B x -> B x -> PropwfA:well_founded leAwfB:forall x : A, well_founded (leB x)forall a : {x : A & B x}, Acc LexProd aA:TypeB:A -> TypeleA:A -> A -> PropleB:forall x0 : A, B x0 -> B x0 -> PropwfA:well_founded leAwfB:forall x0 : A, well_founded (leB x0)x:Ab:B xAcc LexProd (existT B x b)A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x0 : A, B x0 -> B x0 -> PropwfA:well_founded leAwfB:forall x0 : A, well_founded (leB x0)x:Ab:B xAcc (leB x) bauto with sets. Defined. End WfLexicographic_Product. Section Wf_Symmetric_Product. Variable A : Type. Variable B : Type. Variable leA : A -> A -> Prop. Variable leB : B -> B -> Prop. Notation Symprod := (symprod A B leA leB).A:TypeB:A -> TypeleA:A -> A -> PropleB:forall x0 : A, B x0 -> B x0 -> PropwfA:well_founded leAwfB:forall (x0 : A) (a : B x0), Acc (leB x0) ax:Ab:B xAcc (leB x) bA, B:TypeleA:A -> A -> PropleB:B -> B -> Propforall x : A, Acc leA x -> forall y : B, Acc leB y -> Acc Symprod (x, y)A, B:TypeleA:A -> A -> PropleB:B -> B -> Propforall x : A, Acc leA x -> forall y : B, Acc leB y -> Acc Symprod (x, y)A, B:TypeleA:A -> A -> PropleB:B -> B -> Propx:AIHAcc:forall y0 : A, leA y0 x -> forall y1 : B, Acc leB y1 -> Acc Symprod (y0, y1)y:BH2:Acc leB yAcc Symprod (x, y)A, B:TypeleA:A -> A -> PropleB:B -> B -> Propx:AIHAcc:forall y : A, leA y x -> forall y0 : B, Acc leB y0 -> Acc Symprod (y, y0)x1:BH3:forall y : B, leB y x1 -> Acc leB yIHAcc1:forall y : B, leB y x1 -> Acc Symprod (x, y)Acc Symprod (x, x1)A, B:TypeleA:A -> A -> PropleB:B -> B -> Propx:AIHAcc:forall y0 : A, leA y0 x -> forall y1 : B, Acc leB y1 -> Acc Symprod (y0, y1)x1:BH3:forall y0 : B, leB y0 x1 -> Acc leB y0IHAcc1:forall y0 : B, leB y0 x1 -> Acc Symprod (x, y0)y:(A * B)%typeH5:Symprod y (x, x1)Acc Symprod yA, B:TypeleA:A -> A -> PropleB:B -> B -> Propx:AIHAcc:forall y0 : A, leA y0 x -> forall y1 : B, Acc leB y1 -> Acc Symprod (y0, y1)x1:BH3:forall y0 : B, leB y0 x1 -> Acc leB y0IHAcc1:forall y0 : B, leB y0 x1 -> Acc Symprod (x, y0)y:(A * B)%typex0:AH:leA x0 xAcc Symprod (x0, x1)apply Acc_intro; trivial. Defined.A, B:TypeleA:A -> A -> PropleB:B -> B -> Propx:AIHAcc:forall y0 : A, leA y0 x -> forall y1 : B, Acc leB y1 -> Acc Symprod (y0, y1)x1:BH3:forall y0 : B, leB y0 x1 -> Acc leB y0IHAcc1:forall y0 : B, leB y0 x1 -> Acc Symprod (x, y0)y:(A * B)%typex0:AH:leA x0 xAcc leB x1A, B:TypeleA:A -> A -> PropleB:B -> B -> Propwell_founded leA -> well_founded leB -> well_founded SymprodA, B:TypeleA:A -> A -> PropleB:B -> B -> Propwell_founded leA -> well_founded leB -> well_founded SymprodA, B:TypeleA:A -> A -> PropleB:B -> B -> Propwell_founded leA -> well_founded leB -> forall a : A * B, Acc Symprod aapply Acc_symprod; auto with sets. Defined. End Wf_Symmetric_Product. Section Swap. Variable A : Type. Variable R : A -> A -> Prop. Notation SwapProd := (swapprod A R).A, B:TypeleA:A -> A -> PropleB:B -> B -> PropH:well_founded leAH0:well_founded leBa:Ab:BAcc Symprod (a, b)A:TypeR:A -> A -> Propforall x y : A, Acc SwapProd (x, y) -> Acc SwapProd (y, x)A:TypeR:A -> A -> Propforall x y : A, Acc SwapProd (x, y) -> Acc SwapProd (y, x)A:TypeR:A -> A -> Propx, y:AH:Acc SwapProd (x, y)Acc SwapProd (y, x)A:TypeR:A -> A -> Propx, y:AH0:forall y0 : A * A, SwapProd y0 (x, y) -> Acc SwapProd y0Acc SwapProd (y, x)A:TypeR:A -> A -> Propx, y:AH0:forall y0 : A * A, SwapProd y0 (x, y) -> Acc SwapProd y0forall y0 : A * A, SwapProd y0 (y, x) -> Acc SwapProd y0A:TypeR:A -> A -> Propx, y:AH0:forall y0 : A * A, SwapProd y0 (x, y) -> Acc SwapProd y0a, a0:AH:SwapProd (a, a0) (y, x)Acc SwapProd (a, a0)A:TypeR:A -> A -> Propx, y:AH0:forall y0 : A * A, SwapProd y0 (x, y) -> Acc SwapProd y0a, a0:AH:R a ySwapProd (a, x) (x, y)A:TypeR:A -> A -> Propx, y:AH0:forall y0 : A * A, SwapProd y0 (x, y) -> Acc SwapProd y0a, a0:AH:R a0 xSwapProd (y, a0) (x, y)A:TypeR:A -> A -> Propx, y:AH0:forall y0 : A * A, SwapProd y0 (x, y) -> Acc SwapProd y0a, a0:AH:R a0 ySwapProd (x, a0) (x, y)A:TypeR:A -> A -> Propx, y:AH0:forall y0 : A * A, SwapProd y0 (x, y) -> Acc SwapProd y0a, a0:AH:R a xSwapProd (a, y) (x, y)A:TypeR:A -> A -> Propx, y:AH0:forall y0 : A * A, SwapProd y0 (x, y) -> Acc SwapProd y0a, a0:AH:R a ySwapProd (a, x) (x, y)apply right_sym; auto with sets.A:TypeR:A -> A -> Propx, y:AH0:forall y0 : A * A, SwapProd y0 (x, y) -> Acc SwapProd y0a, a0:AH:R a ysymprod A A R R (x, a) (x, y)A:TypeR:A -> A -> Propx, y:AH0:forall y0 : A * A, SwapProd y0 (x, y) -> Acc SwapProd y0a, a0:AH:R a0 xSwapProd (y, a0) (x, y)apply left_sym; auto with sets.A:TypeR:A -> A -> Propx, y:AH0:forall y0 : A * A, SwapProd y0 (x, y) -> Acc SwapProd y0a, a0:AH:R a0 xsymprod A A R R (a0, y) (x, y)A:TypeR:A -> A -> Propx, y:AH0:forall y0 : A * A, SwapProd y0 (x, y) -> Acc SwapProd y0a, a0:AH:R a0 ySwapProd (x, a0) (x, y)apply right_sym; auto with sets.A:TypeR:A -> A -> Propx, y:AH0:forall y0 : A * A, SwapProd y0 (x, y) -> Acc SwapProd y0a, a0:AH:R a0 ysymprod A A R R (x, a0) (x, y)A:TypeR:A -> A -> Propx, y:AH0:forall y0 : A * A, SwapProd y0 (x, y) -> Acc SwapProd y0a, a0:AH:R a xSwapProd (a, y) (x, y)apply left_sym; auto with sets. Defined.A:TypeR:A -> A -> Propx, y:AH0:forall y0 : A * A, SwapProd y0 (x, y) -> Acc SwapProd y0a, a0:AH:R a xsymprod A A R R (a, y) (x, y)A:TypeR:A -> A -> Propforall x y : A, Acc R x -> Acc R y -> Acc SwapProd (x, y)A:TypeR:A -> A -> Propforall x y : A, Acc R x -> Acc R y -> Acc SwapProd (x, y)A:TypeR:A -> A -> Propy, x0:AIHAcc0:forall y0 : A, R y0 x0 -> Acc R y -> Acc SwapProd (y0, y)H2:Acc R yAcc SwapProd (x0, y)A:TypeR:A -> A -> Propy, x0:AIHAcc0:forall y0 : A, R y0 x0 -> Acc R y -> Acc SwapProd (y0, y)H2:Acc R y(forall y0 : A, R y0 x0 -> Acc SwapProd (y0, y)) -> Acc SwapProd (x0, y)A:TypeR:A -> A -> Propy, x0:AIHAcc0:forall y0 : A, R y0 x0 -> Acc R y -> Acc SwapProd (y0, y)H2:Acc R yforall y0 : A, R y0 x0 -> Acc SwapProd (y0, y)A:TypeR:A -> A -> Propy, x0:AIHAcc0:forall y0 : A, R y0 x0 -> Acc R y -> Acc SwapProd (y0, y)H2:Acc R y(forall y0 : A, R y0 x0 -> Acc SwapProd (y0, y)) -> Acc SwapProd (x0, y)A:TypeR:A -> A -> Propy, x0:AH2:Acc R y(forall y0 : A, R y0 x0 -> Acc SwapProd (y0, y)) -> Acc SwapProd (x0, y)A:TypeR:A -> A -> Propx0, x1:AIHAcc1:forall y : A, R y x1 -> (forall y0 : A, R y0 x0 -> Acc SwapProd (y0, y)) -> Acc SwapProd (x0, y)H4:forall y0 : A, R y0 x0 -> Acc SwapProd (y0, x1)Acc SwapProd (x0, x1)A:TypeR:A -> A -> Propx0, x1:AIHAcc1:forall y : A, R y x1 -> (forall y0 : A, R y0 x0 -> Acc SwapProd (y0, y)) -> Acc SwapProd (x0, y)H4:forall y0 : A, R y0 x0 -> Acc SwapProd (y0, x1)(forall y : A, R y x1 -> Acc SwapProd (x0, y)) -> Acc SwapProd (x0, x1)A:TypeR:A -> A -> Propx0, x1:AIHAcc1:forall y : A, R y x1 -> (forall y0 : A, R y0 x0 -> Acc SwapProd (y0, y)) -> Acc SwapProd (x0, y)H4:forall y0 : A, R y0 x0 -> Acc SwapProd (y0, x1)forall y : A, R y x1 -> Acc SwapProd (x0, y)A:TypeR:A -> A -> Propx0, x1:AIHAcc1:forall y : A, R y x1 -> (forall y0 : A, R y0 x0 -> Acc SwapProd (y0, y)) -> Acc SwapProd (x0, y)H4:forall y0 : A, R y0 x0 -> Acc SwapProd (y0, x1)(forall y : A, R y x1 -> Acc SwapProd (x0, y)) -> Acc SwapProd (x0, x1)A:TypeR:A -> A -> Propx0, x1:AH4:forall y0 : A, R y0 x0 -> Acc SwapProd (y0, x1)(forall y : A, R y x1 -> Acc SwapProd (x0, y)) -> Acc SwapProd (x0, x1)A:TypeR:A -> A -> Propx0, x1:AH4:forall y0 : A, R y0 x0 -> Acc SwapProd (y0, x1)H:forall y : A, R y x1 -> Acc SwapProd (x0, y)Acc SwapProd (x0, x1)A:TypeR:A -> A -> Propx0, x1:AH4:forall y0 : A, R y0 x0 -> Acc SwapProd (y0, x1)H:forall y : A, R y x1 -> Acc SwapProd (x0, y)forall y : A * A, SwapProd y (x0, x1) -> Acc SwapProd yA:TypeR:A -> A -> Propx0, x1:AH4:forall y0 : A, R y0 x0 -> Acc SwapProd (y0, x1)H:forall y : A, R y x1 -> Acc SwapProd (x0, y)a, a0:AH5:SwapProd (a, a0) (x0, x1)Acc SwapProd (a, a0)A:TypeR:A -> A -> Propx0, x1:AH4:forall y0 : A, R y0 x0 -> Acc SwapProd (y0, x1)H:forall y : A, R y x1 -> Acc SwapProd (x0, y)a, a0:AH0:symprod A A R R (a, a0) (x0, x1)Acc SwapProd (a, a0)A:TypeR:A -> A -> Propx0, x1:AH4:forall y0 : A, R y0 x0 -> Acc SwapProd (y0, x1)H:forall y : A, R y x1 -> Acc SwapProd (x0, y)a, a0:AH0:symprod A A R R (a0, a) (x0, x1)Acc SwapProd (a, a0)inversion_clear H0; auto with sets.A:TypeR:A -> A -> Propx0, x1:AH4:forall y0 : A, R y0 x0 -> Acc SwapProd (y0, x1)H:forall y : A, R y x1 -> Acc SwapProd (x0, y)a, a0:AH0:symprod A A R R (a, a0) (x0, x1)Acc SwapProd (a, a0)A:TypeR:A -> A -> Propx0, x1:AH4:forall y0 : A, R y0 x0 -> Acc SwapProd (y0, x1)H:forall y : A, R y x1 -> Acc SwapProd (x0, y)a, a0:AH0:symprod A A R R (a0, a) (x0, x1)Acc SwapProd (a, a0)inversion_clear H0; auto with sets.A:TypeR:A -> A -> Propx0, x1:AH4:forall y0 : A, R y0 x0 -> Acc SwapProd (y0, x1)H:forall y : A, R y x1 -> Acc SwapProd (x0, y)a, a0:AH0:symprod A A R R (a0, a) (x0, x1)Acc SwapProd (a0, a)A:TypeR:A -> A -> Propx0, x1:AIHAcc1:forall y : A, R y x1 -> (forall y0 : A, R y0 x0 -> Acc SwapProd (y0, y)) -> Acc SwapProd (x0, y)H4:forall y0 : A, R y0 x0 -> Acc SwapProd (y0, x1)forall y : A, R y x1 -> Acc SwapProd (x0, y)A:TypeR:A -> A -> Propx0, x1:AIHAcc1:forall y0 : A, R y0 x1 -> (forall y1 : A, R y1 x0 -> Acc SwapProd (y1, y0)) -> Acc SwapProd (x0, y0)H4:forall y0 : A, R y0 x0 -> Acc SwapProd (y0, x1)y:AH:R y x1Acc SwapProd (x0, y)A:TypeR:A -> A -> Propx0, x1:AIHAcc1:forall y1 : A, R y1 x1 -> (forall y2 : A, R y2 x0 -> Acc SwapProd (y2, y1)) -> Acc SwapProd (x0, y1)H4:forall y1 : A, R y1 x0 -> Acc SwapProd (y1, x1)y:AH:R y x1y0:AH0:R y0 x0Acc SwapProd (y0, y)A:TypeR:A -> A -> Propx0, x1:AIHAcc1:forall y1 : A, R y1 x1 -> (forall y2 : A, R y2 x0 -> Acc SwapProd (y2, y1)) -> Acc SwapProd (x0, y1)H4:forall y1 : A, R y1 x0 -> Acc SwapProd (y1, x1)y:AH:R y x1y0:AH0:R y0 x0SwapProd (y0, y) (y0, x1)apply right_sym; auto with sets.A:TypeR:A -> A -> Propx0, x1:AIHAcc1:forall y1 : A, R y1 x1 -> (forall y2 : A, R y2 x0 -> Acc SwapProd (y2, y1)) -> Acc SwapProd (x0, y1)H4:forall y1 : A, R y1 x0 -> Acc SwapProd (y1, x1)y:AH:R y x1y0:AH0:R y0 x0symprod A A R R (y0, y) (y0, x1)auto with sets. Defined.A:TypeR:A -> A -> Propy, x0:AIHAcc0:forall y0 : A, R y0 x0 -> Acc R y -> Acc SwapProd (y0, y)H2:Acc R yforall y0 : A, R y0 x0 -> Acc SwapProd (y0, y)A:TypeR:A -> A -> Propwell_founded R -> well_founded SwapProdA:TypeR:A -> A -> Propwell_founded R -> well_founded SwapProdA:TypeR:A -> A -> Propwell_founded R -> forall a : A * A, Acc SwapProd aapply Acc_swapprod; auto with sets. Defined. End Swap.A:TypeR:A -> A -> PropH:well_founded Ra, a0:AAcc SwapProd (a, a0)