theory Prelude_ListNoNumbers__E3
imports "$HETS_ISABELLE_LIB/MainHC"
uses "$HETS_ISABELLE_LIB/prelude"
begin

setup "Header.initialize
       [\"Comp1\", \"IdDef\", \"FlipDef\", \"FstDef\", \"SndDef\",
        \"CurryDef\", \"UncurryDef\", \"NotFalse\", \"NotTrue\",
        \"AndFalse\", \"AndTrue\", \"AndSym\", \"OrDef\", \"OtherwiseDef\",
        \"NotFalse1\", \"NotTrue1\", \"notNot1\", \"notNot2\",
        \"EqualTDef\", \"EqualSymDef\", \"EqualReflex\", \"EqualTransT\",
        \"DiffDef\", \"DiffSymDef\", \"DiffTDef\", \"DiffFDef\", \"TE1\",
        \"TE2\", \"TE3\", \"TE4\", \"IUE1\", \"IUE2\", \"IBE1\", \"IBE2\",
        \"IBE3\", \"IBE4\", \"IBE5\", \"IBE6\", \"IBE7\", \"IBE8\",
        \"IOE01\", \"IOE02\", \"IOE03\", \"IOE04\", \"IOE05\", \"IOE06\",
        \"IOE07\", \"IOE08\", \"IOE09\", \"LeIrreflexivity\",
        \"LeTAsymmetry\", \"LeTTransitive\", \"LeTTotal\", \"GeDef\",
        \"GeIrreflexivity\", \"GeTAsymmetry\", \"GeTTransitive\",
        \"GeTTotal\", \"LeqDef\", \"LeqReflexivity\", \"LeqTTransitive\",
        \"LeqTTotal\", \"GeqDef\", \"GeqReflexivity\", \"GeqTTransitive\",
        \"GeqTTotal\", \"EqTSOrdRel\", \"EqFSOrdRel\", \"EqTOrdRel\",
        \"EqFOrdRel\", \"EqTOrdTSubstE\", \"EqTOrdFSubstE\",
        \"EqTOrdTSubstD\", \"EqTOrdFSubstD\", \"LeTGeFEqFRel\",
        \"LeFGeTEqTRel\", \"LeTGeTRel\", \"LeFGeFRel\", \"LeqTGetTRel\",
        \"LeqFGetFRel\", \"GeTLeTRel\", \"GeFLeFRel\", \"GeqTLeqTRel\",
        \"GeqFLeqFRel\", \"LeqTGeFRel\", \"LeqFGeTRel\", \"GeTLeFEqFRel\",
        \"GeFLeTEqTRel\", \"GeqTLeFRel\", \"GeqFLeTRel\",
        \"LeqTLeTEqTRel\", \"LeqFLeFEqFRel\", \"GeqTGeTEqTRel\",
        \"GeqFGeFEqFRel\", \"LeTGeqFRel\", \"GeTLeqFRel\", \"LeLeqDiff\",
        \"CmpLTDef\", \"CmpEQDef\", \"CmpGTDef\", \"MaxYDef\", \"MaxXDef\",
        \"MinXDef\", \"MinYDef\", \"MaxSym\", \"MinSym\", \"TO1\", \"TO3\",
        \"TO4\", \"TO5\", \"TO6\", \"IUO01\", \"IUO02\", \"IUO03\",
        \"IUO04\", \"IUO05\", \"IUO06\", \"IUO07\", \"IOO13\", \"IOO14\",
        \"IOO15\", \"IOO16\", \"IOO17\", \"IOO18\", \"IOO19\", \"IOO20\",
        \"IOO21\", \"IOO22\", \"IOO23\", \"IOO24\", \"IOO25\", \"IOO26\",
        \"IOO27\", \"IOO28\", \"IOO29\", \"IOO30\", \"IOO31\", \"IOO32\",
        \"IOO33\", \"IBO5\", \"IBO6\", \"IBO7\", \"IBO8\", \"IBO9\",
        \"IBO10\", \"IBO11\", \"IBO12\", \"NotDefHead\", \"HeadDef\",
        \"NotDefTail\", \"TailDef\", \"FoldrNil\", \"FoldrCons\",
        \"FoldlNil\", \"FoldlCons\", \"MapNil\", \"MapCons\",
        \"XPlusXPlusNil\", \"XPlusXPlusCons\", \"FilterNil\",
        \"FilterConsT\", \"FilterConsF\", \"ILE02\", \"ILO05\", \"ILO06\",
        \"ILO07\", \"ILE01\", \"ILO01\", \"ILO02\", \"ILO03\", \"ILO04\",
        \"ILO08\", \"ILO09\", \"ILO10\", \"ILO11\", \"ILO12\", \"ILO13\",
        \"ILO14\", \"ILO15\", \"ILO16\", \"ILO17\", \"ILO18\", \"ILO19\",
        \"ILO20\", \"ILO21\", \"ILO22\", \"FoldlDecomp\", \"MapDecomp\",
        \"MapFunctor\", \"FilterProm\"]"

typedecl Bool
typedecl ('a1) DList
typedecl Unit
typedecl X_Nat

datatype Ordering = EQ | GT | LT
datatype 'a List = X_Cons "'a partial" "'a List partial" |
                   X_Nil ("Nil''")

consts
X__XAmpXAmp__X :: "bool => bool => bool" ("(_/ &&/ _)" [54,54] 52)
X__XEqXEq__X :: "'a partial => 'a partial => bool" ("(_/ ==''/ _)" [54,54] 52)
X__XGtXEq__X :: "'a partial => 'a partial => bool" ("(_/ >=''/ _)" [54,54] 52)
X__XGt__X :: "'a partial => 'a partial => bool" ("(_/ >''/ _)" [54,54] 52)
X__XLtXEq__X :: "'a partial => 'a partial => bool" ("(_/ <=''/ _)" [54,54] 52)
X__XLt__X :: "'a partial => 'a partial => bool" ("(_/ <''/ _)" [54,54] 52)
X__XPlusXPlus__X :: "'a List partial => 'a List partial => 'a List partial" ("(_/ ++''/ _)" [54,54] 52)
X__XSlashXEq__X :: "'a partial => 'a partial => bool" ("(_/ '/=/ _)" [54,54] 52)
X__XVBarXVBar__X :: "bool => bool => bool" ("(_/ ||/ _)" [54,54] 52)
X__o__X :: "('b partial => 'c partial) * ('a partial => 'b partial) => 'a partial => 'c partial"
X_curry :: "('a partial * 'b partial => 'c partial) => 'a partial => 'b partial => 'c partial"
X_filter :: "('a partial => bool) => 'a List partial => 'a List partial"
X_flip :: "('a partial => 'b partial => 'c partial) => 'b partial => 'a partial => 'c partial"
X_foldl :: "('a partial => 'b partial => 'a partial) => 'a partial => 'b List partial => 'a partial"
X_foldr :: "('a partial => 'b partial => 'b partial) => 'b partial => 'a List partial => 'b partial"
X_fst :: "'a partial => 'b partial => 'a partial" ("fst''/'(_,/ _')" [3,3] 999)
X_head :: "'a List partial => 'a partial" ("head/'(_')" [3] 999)
X_id :: "'a partial => 'a partial" ("id''/'(_')" [3] 999)
X_map :: "('a partial => 'b partial) => 'a List partial => 'b List partial"
X_max :: "'a partial => 'a partial => 'a partial"
X_min :: "'a partial => 'a partial => 'a partial"
X_snd :: "'a partial => 'b partial => 'b partial" ("snd''/'(_,/ _')" [3,3] 999)
X_tail :: "'a List partial => 'a List partial" ("tail/'(_')" [3] 999)
compare :: "'a partial => 'a partial => Ordering partial"
notH__X :: "bool => bool" ("(notH/ _)" [56] 56)
otherwiseH :: "bool"
uncurry :: "('a partial => 'b partial => 'c partial) => 'a partial * 'b partial => 'c partial"

axioms
Comp1 [rule_format] :
"ALL (f :: 'b partial => 'c partial).
 ALL (g :: 'a partial => 'b partial).
 X__o__X (f, g) = (% x. f (g (makePartial x))) o makeTotal"

IdDef [rule_format] : "ALL (x :: 'a partial). id'(x) = x"

FlipDef [rule_format] :
"ALL (f :: 'a partial => 'b partial => 'c partial).
 ALL (x :: 'a partial). ALL (y :: 'b partial). X_flip f y x = f x y"

FstDef [rule_format] :
"ALL (x :: 'a partial). ALL (y :: 'b partial). fst'(x, y) = x"

SndDef [rule_format] :
"ALL (x :: 'a partial). ALL (y :: 'b partial). snd'(x, y) = y"

CurryDef [rule_format] :
"ALL (g :: 'a partial * 'b partial => 'c partial).
 ALL (x :: 'a partial).
 ALL (y :: 'b partial). X_curry g x y = g (x, y)"

UncurryDef [rule_format] :
"ALL (f :: 'a partial => 'b partial => 'c partial).
 ALL (x :: 'a partial).
 ALL (y :: 'b partial). uncurry f (x, y) = f x y"

NotFalse [rule_format] : "notH False"

NotTrue [rule_format] : "~ notH True"

AndFalse [rule_format] : "ALL (x :: bool). ~ False && x"

AndTrue [rule_format] : "ALL (x :: bool). True && x = x"

AndSym [rule_format] :
"ALL (x :: bool). ALL (y :: bool). x && y = y && x"

OrDef [rule_format] :
"ALL (x :: bool).
 ALL (y :: bool). x || y = notH (notH x && notH y)"

OtherwiseDef [rule_format] : "otherwiseH"

NotFalse1 [rule_format] : "ALL (x :: bool). notH x = (~ x)"

NotTrue1 [rule_format] : "ALL (x :: bool). ~ notH x = x"

notNot1 [rule_format] : "ALL (x :: bool). (~ x) = notH x"

notNot2 [rule_format] : "ALL (x :: bool). (~ ~ x) = (~ notH x)"

EqualTDef [rule_format] :
"ALL (x :: 'a partial). ALL (y :: 'a partial). x = y --> x ==' y"

EqualSymDef [rule_format] :
"ALL (x :: 'a partial). ALL (y :: 'a partial). x ==' y = y ==' x"

EqualReflex [rule_format] : "ALL (x :: 'a partial). x ==' x"

EqualTransT [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial).
 ALL (z :: 'a partial). x ==' y & y ==' z --> x ==' z"

DiffDef [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). x /= y = notH (x ==' y)"

DiffSymDef [rule_format] :
"ALL (x :: 'a partial). ALL (y :: 'a partial). x /= y = y /= x"

DiffTDef [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). x /= y = notH (x ==' y)"

DiffFDef [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). (~ x /= y) = x ==' y"

TE1 [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). ~ x ==' y --> ~ x = y"

TE2 [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). notH (x ==' y) = (~ x ==' y)"

TE3 [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). (~ notH (x ==' y)) = x ==' y"

TE4 [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). (~ x ==' y) = (~ x ==' y)"

IUE1 [rule_format] : "makePartial () ==' makePartial ()"

IUE2 [rule_format] : "~ makePartial () /= makePartial ()"

IBE1 [rule_format] : "makePartial () ==' makePartial ()"

IBE2 [rule_format] : "undefinedOp ==' undefinedOp"

IBE3 [rule_format] : "~ undefinedOp ==' makePartial ()"

IBE4 [rule_format] : "~ makePartial () ==' undefinedOp"

IBE5 [rule_format] : "makePartial () /= undefinedOp"

IBE6 [rule_format] : "undefinedOp /= makePartial ()"

IBE7 [rule_format] : "notH (makePartial () ==' undefinedOp)"

IBE8 [rule_format] : "~ notH notH (makePartial () ==' undefinedOp)"

IOE01 [rule_format] : "makePartial LT ==' makePartial LT"

IOE02 [rule_format] : "makePartial EQ ==' makePartial EQ"

IOE03 [rule_format] : "makePartial GT ==' makePartial GT"

IOE04 [rule_format] : "~ makePartial LT ==' makePartial EQ"

IOE05 [rule_format] : "~ makePartial LT ==' makePartial GT"

IOE06 [rule_format] : "~ makePartial EQ ==' makePartial GT"

IOE07 [rule_format] : "makePartial LT /= makePartial EQ"

IOE08 [rule_format] : "makePartial LT /= makePartial GT"

IOE09 [rule_format] : "makePartial EQ /= makePartial GT"

LeIrreflexivity [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). x ==' y --> ~ x <' y"

LeTAsymmetry [rule_format] :
"ALL (x :: 'a partial). ALL (y :: 'a partial). x <' y --> ~ y <' x"

LeTTransitive [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial).
 ALL (z :: 'a partial). x <' y & y <' z --> x <' z"

LeTTotal [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). (x <' y | y <' x) | x ==' y"

GeDef [rule_format] :
"ALL (x :: 'a partial). ALL (y :: 'a partial). x >' y = y <' x"

GeIrreflexivity [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). x ==' y --> ~ x >' y"

GeTAsymmetry [rule_format] :
"ALL (x :: 'a partial). ALL (y :: 'a partial). x >' y --> ~ y >' x"

GeTTransitive [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial).
 ALL (z :: 'a partial). (x >' y) && (y >' z) --> x >' z"

GeTTotal [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). ((x >' y) || (y >' x)) || (x ==' y)"

LeqDef [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). x <=' y = (x <' y) || (x ==' y)"

LeqReflexivity [rule_format] : "ALL (x :: 'a partial). x <=' x"

LeqTTransitive [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial).
 ALL (z :: 'a partial). (x <=' y) && (y <=' z) --> x <=' z"

LeqTTotal [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). (x <=' y) && (y <=' x) = x ==' y"

GeqDef [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). x >=' y = (x >' y) || (x ==' y)"

GeqReflexivity [rule_format] : "ALL (x :: 'a partial). x >=' x"

GeqTTransitive [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial).
 ALL (z :: 'a partial). (x >=' y) && (y >=' z) --> x >=' z"

GeqTTotal [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). (x >=' y) && (y >=' x) = x ==' y"

EqTSOrdRel [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). x ==' y = (~ x <' y & ~ x >' y)"

EqFSOrdRel [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). (~ x ==' y) = (x <' y | x >' y)"

EqTOrdRel [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). x ==' y = (x <=' y & x >=' y)"

EqFOrdRel [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). (~ x ==' y) = (x <=' y | x >=' y)"

EqTOrdTSubstE [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial).
 ALL (z :: 'a partial). x ==' y & y <' z --> x <' z"

EqTOrdFSubstE [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial).
 ALL (z :: 'a partial). x ==' y & ~ y <' z --> ~ x <' z"

EqTOrdTSubstD [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial).
 ALL (z :: 'a partial). x ==' y & z <' y --> z <' x"

EqTOrdFSubstD [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial).
 ALL (z :: 'a partial). x ==' y & ~ z <' y --> ~ z <' x"

LeTGeFEqFRel [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). x <' y = (~ x >' y & ~ x ==' y)"

LeFGeTEqTRel [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). (~ x <' y) = (x >' y | x ==' y)"

LeTGeTRel [rule_format] :
"ALL (x :: 'a partial). ALL (y :: 'a partial). x <' y = y >' x"

LeFGeFRel [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). (~ x <' y) = (~ y >' x)"

LeqTGetTRel [rule_format] :
"ALL (x :: 'a partial). ALL (y :: 'a partial). x <=' y = y >=' x"

LeqFGetFRel [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). (~ x <=' y) = (~ y >=' x)"

GeTLeTRel [rule_format] :
"ALL (x :: 'a partial). ALL (y :: 'a partial). x >' y = y <' x"

GeFLeFRel [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). (~ x >' y) = (~ y <' x)"

GeqTLeqTRel [rule_format] :
"ALL (x :: 'a partial). ALL (y :: 'a partial). x >=' y = y <=' x"

GeqFLeqFRel [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). (~ x >=' y) = (~ y <=' x)"

LeqTGeFRel [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). x <=' y = (~ x >' y)"

LeqFGeTRel [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). (~ x <=' y) = x >' y"

GeTLeFEqFRel [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). x >' y = (~ x <' y & ~ x ==' y)"

GeFLeTEqTRel [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). (~ x >' y) = (x <' y | x ==' y)"

GeqTLeFRel [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). x >=' y = (~ x <' y)"

GeqFLeTRel [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). (~ x >=' y) = x <' y"

LeqTLeTEqTRel [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). x <=' y = (x <' y | x ==' y)"

LeqFLeFEqFRel [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). (~ x <=' y) = (~ x <' y & ~ x ==' y)"

GeqTGeTEqTRel [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). x >=' y = (x >' y | x ==' y)"

GeqFGeFEqFRel [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). (~ x >=' y) = (~ x >' y & ~ x ==' y)"

LeTGeqFRel [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). x <' y = (~ x >=' y)"

GeTLeqFRel [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). x >' y = (~ x <=' y)"

LeLeqDiff [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). x <' y = (x <=' y) && (x /= y)"

CmpLTDef [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). compare x y ==' makePartial LT = x <' y"

CmpEQDef [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). compare x y ==' makePartial EQ = x ==' y"

CmpGTDef [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). compare x y ==' makePartial GT = x >' y"

MaxYDef [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). X_max x y ==' y = x <=' y"

MaxXDef [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). X_max x y ==' x = y <=' x"

MinXDef [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). X_min x y ==' x = x <=' y"

MinYDef [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). X_min x y ==' y = y <=' x"

MaxSym [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). X_max x y ==' y = X_max y x ==' y"

MinSym [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). X_min x y ==' y = X_min y x ==' y"

TO1 [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). (x ==' y | x <' y) = x <=' y"

TO3 [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). notH notH (x <' y) | notH (x <' y)"

TO4 [rule_format] :
"ALL (x :: 'a partial).
 ALL (y :: 'a partial). x <' y --> notH (x ==' y)"

TO5 [rule_format] :
"ALL (w :: 'a partial).
 ALL (x :: 'a partial).
 ALL (y :: 'a partial).
 ALL (z :: 'a partial). (x <' y & y <' z) & z <' w --> x <' w"

TO6 [rule_format] :
"ALL (x :: 'a partial).
 ALL (z :: 'a partial). z <' x --> notH (x <' z)"

IUO01 [rule_format] : "makePartial () <=' makePartial ()"

IUO02 [rule_format] : "~ makePartial () <' makePartial ()"

IUO03 [rule_format] : "makePartial () >=' makePartial ()"

IUO04 [rule_format] : "~ makePartial () >' makePartial ()"

IUO05 [rule_format] :
"X_max (makePartial ()) (makePartial ()) ==' makePartial ()"

IUO06 [rule_format] :
"X_min (makePartial ()) (makePartial ()) ==' makePartial ()"

IUO07 [rule_format] :
"compare (makePartial ()) (makePartial ()) ==' makePartial EQ"

IOO13 [rule_format] : "makePartial LT <' makePartial EQ"

IOO14 [rule_format] : "makePartial EQ <' makePartial GT"

IOO15 [rule_format] : "makePartial LT <' makePartial GT"

IOO16 [rule_format] : "makePartial LT <=' makePartial EQ"

IOO17 [rule_format] : "makePartial EQ <=' makePartial GT"

IOO18 [rule_format] : "makePartial LT <=' makePartial GT"

IOO19 [rule_format] : "makePartial EQ >=' makePartial LT"

IOO20 [rule_format] : "makePartial GT >=' makePartial EQ"

IOO21 [rule_format] : "makePartial GT >=' makePartial LT"

IOO22 [rule_format] : "makePartial EQ >' makePartial LT"

IOO23 [rule_format] : "makePartial GT >' makePartial EQ"

IOO24 [rule_format] : "makePartial GT >' makePartial LT"

IOO25 [rule_format] :
"X_max (makePartial LT) (makePartial EQ) ==' makePartial EQ"

IOO26 [rule_format] :
"X_max (makePartial EQ) (makePartial GT) ==' makePartial GT"

IOO27 [rule_format] :
"X_max (makePartial LT) (makePartial GT) ==' makePartial GT"

IOO28 [rule_format] :
"X_min (makePartial LT) (makePartial EQ) ==' makePartial LT"

IOO29 [rule_format] :
"X_min (makePartial EQ) (makePartial GT) ==' makePartial EQ"

IOO30 [rule_format] :
"X_min (makePartial LT) (makePartial GT) ==' makePartial LT"

IOO31 [rule_format] :
"compare (makePartial LT) (makePartial LT) ==' makePartial EQ"

IOO32 [rule_format] :
"compare (makePartial EQ) (makePartial EQ) ==' makePartial EQ"

IOO33 [rule_format] :
"compare (makePartial GT) (makePartial GT) ==' makePartial EQ"

IBO5 [rule_format] : "undefinedOp <' makePartial ()"

IBO6 [rule_format] : "~ undefinedOp >=' makePartial ()"

IBO7 [rule_format] : "makePartial () >=' undefinedOp"

IBO8 [rule_format] : "~ makePartial () <' undefinedOp"

IBO9 [rule_format] :
"X_max undefinedOp (makePartial ()) ==' makePartial ()"

IBO10 [rule_format] :
"X_min undefinedOp (makePartial ()) ==' undefinedOp"

IBO11 [rule_format] :
"compare (makePartial ()) (makePartial ()) ==' makePartial EQ"

IBO12 [rule_format] :
"compare undefinedOp undefinedOp ==' makePartial EQ"

NotDefHead [rule_format] : "~ defOp (head(makePartial Nil'))"

HeadDef [rule_format] :
"ALL (x :: 'a partial).
 ALL (xs :: 'a List partial). head(makePartial (X_Cons x xs)) = x"

NotDefTail [rule_format] : "~ defOp (tail(makePartial Nil'))"

TailDef [rule_format] :
"ALL (x :: 'a partial).
 ALL (xs :: 'a List partial). tail(makePartial (X_Cons x xs)) = xs"

FoldrNil [rule_format] :
"ALL (f :: 'a partial => 'b partial => 'b partial).
 ALL (s :: 'b partial). X_foldr f s (makePartial Nil') = s"

FoldrCons [rule_format] :
"ALL (f :: 'a partial => 'b partial => 'b partial).
 ALL (s :: 'b partial).
 ALL (x :: 'a partial).
 ALL (xs :: 'a List partial).
 X_foldr f s (makePartial (X_Cons x xs)) = f x (X_foldr f s xs)"

FoldlNil [rule_format] :
"ALL (g :: 'a partial => 'b partial => 'a partial).
 ALL (t :: 'a partial). X_foldl g t (makePartial Nil') = t"

FoldlCons [rule_format] :
"ALL (g :: 'a partial => 'b partial => 'a partial).
 ALL (t :: 'a partial).
 ALL (z :: 'b partial).
 ALL (zs :: 'b List partial).
 X_foldl g t (makePartial (X_Cons z zs)) = X_foldl g (g t z) zs"

MapNil [rule_format] :
"ALL (h :: 'a partial => 'b partial).
 X_map h (makePartial Nil') = makePartial Nil'"

MapCons [rule_format] :
"ALL (h :: 'a partial => 'b partial).
 ALL (x :: 'a partial).
 ALL (xs :: 'a List partial).
 X_map h (makePartial (X_Cons x xs)) =
 makePartial (X_Cons (h x) (X_map h xs))"

XPlusXPlusNil [rule_format] :
"ALL (l :: 'a List partial). makePartial Nil' ++' l = l"

XPlusXPlusCons [rule_format] :
"ALL (l :: 'a List partial).
 ALL (x :: 'a partial).
 ALL (xs :: 'a List partial).
 makePartial (X_Cons x xs) ++' l =
 makePartial (X_Cons x (xs ++' l))"

FilterNil [rule_format] :
"ALL (p :: 'a partial => bool).
 X_filter p (makePartial Nil') = makePartial Nil'"

FilterConsT [rule_format] :
"ALL (p :: 'a partial => bool).
 ALL (x :: 'a partial).
 ALL (xs :: 'a List partial).
 p x -->
 X_filter p (makePartial (X_Cons x xs)) =
 makePartial (X_Cons x (X_filter p xs))"

FilterConsF [rule_format] :
"ALL (p :: 'a partial => bool).
 ALL (x :: 'a partial).
 ALL (xs :: 'a List partial).
 ~ p x --> X_filter p (makePartial (X_Cons x xs)) = X_filter p xs"

ILE02 [rule_format] :
"ALL (x :: 'a partial).
 ALL (xs :: 'a List partial).
 ALL (y :: 'a partial).
 ALL (ys :: 'a List partial).
 makePartial (X_Cons x xs) ==' makePartial (X_Cons y ys) =
 (x ==' y) && (xs ==' ys)"

ILO05 [rule_format] :
"ALL (w :: 'b partial).
 ALL (ws :: 'b List partial).
 ALL (z :: 'b partial).
 ALL (zs :: 'b List partial).
 z <' w --> makePartial (X_Cons z zs) <' makePartial (X_Cons w ws)"

ILO06 [rule_format] :
"ALL (w :: 'b partial).
 ALL (ws :: 'b List partial).
 ALL (z :: 'b partial).
 ALL (zs :: 'b List partial).
 z ==' w -->
 makePartial (X_Cons z zs) <' makePartial (X_Cons w ws) = zs <' ws"

ILO07 [rule_format] :
"ALL (w :: 'b partial).
 ALL (ws :: 'b List partial).
 ALL (z :: 'b partial).
 ALL (zs :: 'b List partial).
 ~ z <' w & ~ z ==' w -->
 ~ makePartial (X_Cons z zs) <' makePartial (X_Cons w ws)"

declare IdDef [simp]
declare FlipDef [simp]
declare FstDef [simp]
declare SndDef [simp]
declare CurryDef [simp]
declare UncurryDef [simp]
declare NotFalse [simp]
declare NotTrue [simp]
declare AndFalse [simp]
declare AndTrue [simp]
declare OtherwiseDef [simp]
declare NotTrue1 [simp]
declare EqualReflex [simp]
declare IUE1 [simp]
declare IUE2 [simp]
declare IBE1 [simp]
declare IBE2 [simp]
declare IBE3 [simp]
declare IBE4 [simp]
declare IBE5 [simp]
declare IBE6 [simp]
declare IBE7 [simp]
declare IBE8 [simp]
declare IOE01 [simp]
declare IOE02 [simp]
declare IOE03 [simp]
declare IOE04 [simp]
declare IOE05 [simp]
declare IOE06 [simp]
declare IOE07 [simp]
declare IOE08 [simp]
declare IOE09 [simp]
declare LeIrreflexivity [simp]
declare LeTAsymmetry [simp]
declare GeIrreflexivity [simp]
declare GeTAsymmetry [simp]
declare GeTTransitive [simp]
declare GeTTotal [simp]
declare LeqReflexivity [simp]
declare LeqTTransitive [simp]
declare LeqTTotal [simp]
declare GeqReflexivity [simp]
declare GeqTTransitive [simp]
declare GeqTTotal [simp]
declare CmpLTDef [simp]
declare CmpEQDef [simp]
declare CmpGTDef [simp]
declare MaxYDef [simp]
declare MaxXDef [simp]
declare MinXDef [simp]
declare MinYDef [simp]
declare TO4 [simp]
declare TO6 [simp]
declare IUO01 [simp]
declare IUO02 [simp]
declare IUO03 [simp]
declare IUO04 [simp]
declare IUO05 [simp]
declare IUO06 [simp]
declare IUO07 [simp]
declare IOO13 [simp]
declare IOO14 [simp]
declare IOO15 [simp]
declare IOO16 [simp]
declare IOO17 [simp]
declare IOO18 [simp]
declare IOO19 [simp]
declare IOO20 [simp]
declare IOO21 [simp]
declare IOO22 [simp]
declare IOO23 [simp]
declare IOO24 [simp]
declare IOO25 [simp]
declare IOO26 [simp]
declare IOO27 [simp]
declare IOO28 [simp]
declare IOO29 [simp]
declare IOO30 [simp]
declare IOO31 [simp]
declare IOO32 [simp]
declare IOO33 [simp]
declare IBO5 [simp]
declare IBO6 [simp]
declare IBO7 [simp]
declare IBO8 [simp]
declare IBO9 [simp]
declare IBO10 [simp]
declare IBO11 [simp]
declare IBO12 [simp]
declare NotDefHead [simp]
declare HeadDef [simp]
declare NotDefTail [simp]
declare TailDef [simp]
declare FoldrNil [simp]
declare FoldrCons [simp]
declare FoldlNil [simp]
declare FoldlCons [simp]
declare MapNil [simp]
declare XPlusXPlusNil [simp]
declare FilterNil [simp]
declare FilterConsF [simp]
declare ILE02 [simp]
declare ILO05 [simp]
declare ILO06 [simp]

theorem ILE01 : "makePartial Nil' ==' makePartial Nil'"
by (auto)

setup "Header.record \"ILE01\""

theorem ILO01 : "~ makePartial Nil' <' makePartial Nil'"
by (auto)

setup "Header.record \"ILO01\""

theorem ILO02 : "makePartial Nil' <=' makePartial Nil'"
by (auto)

setup "Header.record \"ILO02\""

theorem ILO03 : "~ makePartial Nil' >' makePartial Nil'"
by (auto)

setup "Header.record \"ILO03\""

theorem ILO04 : "makePartial Nil' >=' makePartial Nil'"
by (auto)

setup "Header.record \"ILO04\""

theorem ILO08 :
"ALL (w :: 'b partial).
 ALL (ws :: 'b List partial).
 ALL (z :: 'b partial).
 ALL (zs :: 'b List partial).
 makePartial (X_Cons z zs) <=' makePartial (X_Cons w ws) =
 (makePartial (X_Cons z zs) <' makePartial (X_Cons w ws)) ||
 (makePartial (X_Cons z zs) ==' makePartial (X_Cons w ws))"
apply(rule allI)+
apply(simp only: LeqDef)
done

setup "Header.record \"ILO08\""

theorem ILO09 :
"ALL (w :: 'b partial).
 ALL (ws :: 'b List partial).
 ALL (z :: 'b partial).
 ALL (zs :: 'b List partial).
 makePartial (X_Cons z zs) >' makePartial (X_Cons w ws) =
 makePartial (X_Cons w ws) <' makePartial (X_Cons z zs)"
apply(rule allI)+
apply(simp only: GeDef)
done

setup "Header.record \"ILO09\""

theorem ILO10 :
"ALL (w :: 'b partial).
 ALL (ws :: 'b List partial).
 ALL (z :: 'b partial).
 ALL (zs :: 'b List partial).
 makePartial (X_Cons z zs) >=' makePartial (X_Cons w ws) =
 (makePartial (X_Cons z zs) >' makePartial (X_Cons w ws)) ||
 (makePartial (X_Cons z zs) ==' makePartial (X_Cons w ws))"
apply(rule allI)+
apply(simp only: GeqDef)
done

setup "Header.record \"ILO10\""

theorem ILO11 :
"compare (makePartial Nil') (makePartial Nil') ==' makePartial EQ =
 makePartial Nil' ==' makePartial Nil'"
by (auto)

setup "Header.record \"ILO11\""

theorem ILO12 :
"compare (makePartial Nil') (makePartial Nil') ==' makePartial LT =
 makePartial Nil' <' makePartial Nil'"
by (auto)

setup "Header.record \"ILO12\""

theorem ILO13 :
"compare (makePartial Nil') (makePartial Nil') ==' makePartial GT =
 makePartial Nil' >' makePartial Nil'"
by (auto)

setup "Header.record \"ILO13\""

theorem ILO14 :
"ALL (w :: 'b partial).
 ALL (ws :: 'b List partial).
 ALL (z :: 'b partial).
 ALL (zs :: 'b List partial).
 compare (makePartial (X_Cons z zs)) (makePartial (X_Cons w ws)) =='
 makePartial EQ =
 makePartial (X_Cons z zs) ==' makePartial (X_Cons w ws)"
by (auto)

setup "Header.record \"ILO14\""

theorem ILO15 :
"ALL (w :: 'b partial).
 ALL (ws :: 'b List partial).
 ALL (z :: 'b partial).
 ALL (zs :: 'b List partial).
 compare (makePartial (X_Cons z zs)) (makePartial (X_Cons w ws)) =='
 makePartial LT =
 makePartial (X_Cons z zs) <' makePartial (X_Cons w ws)"
by (auto)

setup "Header.record \"ILO15\""

theorem ILO16 :
"ALL (w :: 'b partial).
 ALL (ws :: 'b List partial).
 ALL (z :: 'b partial).
 ALL (zs :: 'b List partial).
 compare (makePartial (X_Cons z zs)) (makePartial (X_Cons w ws)) =='
 makePartial GT =
 makePartial (X_Cons z zs) >' makePartial (X_Cons w ws)"
apply(rule allI)+
apply(simp only: CmpGTDef)
done

setup "Header.record \"ILO16\""

theorem ILO17 :
"X_max (makePartial Nil') (makePartial Nil') ==' makePartial Nil' =
 makePartial Nil' <=' makePartial Nil'"
by (auto)

setup "Header.record \"ILO17\""

theorem ILO18 :
"X_min (makePartial Nil') (makePartial Nil') ==' makePartial Nil' =
 makePartial Nil' <=' makePartial Nil'"
by (auto)

setup "Header.record \"ILO18\""

theorem ILO19 :
"ALL (w :: 'b partial).
 ALL (ws :: 'b List partial).
 ALL (z :: 'b partial).
 ALL (zs :: 'b List partial).
 makePartial (X_Cons z zs) <=' makePartial (X_Cons w ws) =
 X_max (makePartial (X_Cons z zs)) (makePartial (X_Cons w ws)) =='
 makePartial (X_Cons w ws)"
apply(rule allI)+
apply(simp add: LeqDef)
done

setup "Header.record \"ILO19\""

theorem ILO20 :
"ALL (w :: 'b partial).
 ALL (ws :: 'b List partial).
 ALL (z :: 'b partial).
 ALL (zs :: 'b List partial).
 makePartial (X_Cons w ws) <=' makePartial (X_Cons z zs) =
 X_max (makePartial (X_Cons z zs)) (makePartial (X_Cons w ws)) =='
 makePartial (X_Cons z zs)"
apply(rule allI)+
apply(simp add: LeqDef)
done

setup "Header.record \"ILO20\""

theorem ILO21 :
"ALL (w :: 'b partial).
 ALL (ws :: 'b List partial).
 ALL (z :: 'b partial).
 ALL (zs :: 'b List partial).
 makePartial (X_Cons z zs) <=' makePartial (X_Cons w ws) =
 X_min (makePartial (X_Cons z zs)) (makePartial (X_Cons w ws)) =='
 makePartial (X_Cons z zs)"
apply(rule allI)+
apply(simp add: LeqDef)
done

setup "Header.record \"ILO21\""

theorem ILO22 :
"ALL (w :: 'b partial).
 ALL (ws :: 'b List partial).
 ALL (z :: 'b partial).
 ALL (zs :: 'b List partial).
 makePartial (X_Cons w ws) <=' makePartial (X_Cons z zs) =
 X_min (makePartial (X_Cons z zs)) (makePartial (X_Cons w ws)) =='
 makePartial (X_Cons w ws)"
apply(rule allI)+
apply(simp add: LeqDef)
done

setup "Header.record \"ILO22\""

theorem FoldlDecomp :
"ALL (e :: 'a partial).
 ALL (i :: 'a partial => 'b partial => 'a partial).
 ALL (ts :: 'b List partial).
 ALL (ys :: 'b List partial).
 X_foldl i e (ys ++' ts) = X_foldl i (X_foldl i e ys) ts"
oops

setup "Header.record \"FoldlDecomp\""

theorem MapDecomp :
"ALL (f :: 'a partial => 'b partial).
 ALL (xs :: 'a List partial).
 ALL (zs :: 'a List partial).
 X_map f (xs ++' zs) = X_map f xs ++' X_map f zs"
(*
apply(auto)
apply(case_tac xs)
apply(auto)
apply(simp add: MapCons)
apply(simp add: XPlusXPlusNil MapCons XPlusXPlusCons)
done
*)
sorry

setup "Header.record \"MapDecomp\""

theorem MapFunctor :
"ALL (f :: 'a partial => 'b partial).
 ALL (g :: 'b partial => 'c partial).
 ALL (xs :: 'a List partial).
 X_map (X__o__X (g, f)) xs = X_map g (X_map f xs)"
(*
apply(auto)
apply(induct_tac xs)
apply(auto)
apply(simp add: MapNil MapCons Comp1)
done
*)
sorry

setup "Header.record \"MapFunctor\""

theorem FilterProm :
"ALL (f :: 'a partial => 'b partial).
 ALL (p :: 'b partial => bool).
 ALL (xs :: 'a List partial).
 X_filter p (X_map f xs) =
 X_map f (X_filter (id o defOp o X__o__X (bool2partial o p, f)) xs)"
(*
apply(auto)
apply(induct_tac xs)
apply(simp only: Comp1)
apply(simp only: bool2partial_def makePartial_def makeTotal_def)
apply(auto)
apply(case_tac "p(f a)")
apply(auto)
apply(simp add: MapCons)
apply(simp add: FilterConsT)
apply(simp add: MapCons)
apply(simp add: FilterConsT)
done
*)

setup "Header.record \"FilterProm\""

end


(*  Title:       Deriving class instances for datatypes
    Author:      René Thiemann       <rene.thiemann@uibk.ac.at>
    Maintainer:  René Thiemann
    License:     LGPL
*)

(*
Copyright 2013 René Thiemann

This file is part of IsaFoR/CeTA.

IsaFoR/CeTA is free software: you can redistribute it and/or modify it under the
terms of the GNU Lesser General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.

IsaFoR/CeTA is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along
with IsaFoR/CeTA. If not, see <http://www.gnu.org/licenses/>.
*)

header {* Generating linear orders for datatypes *}

theory Order_Generator
imports Derive_Manager
begin

subsection Introduction

text {*

The order generator registers itself at the derive-manager for the classes @{class ord},
@{class order}, and @{class linorder}.
To be more precise,
it automatically generates the two functions @{term "op \<le>"} and @{term "op <"} for some datatype
\texttt{dtype} and
proves the following instantiations.

\begin{itemize}
\item \texttt{instantiation dtype :: (ord,\ldots,ord) ord}
\item \texttt{instantiation dtype :: (order,\ldots,order) order}
\item \texttt{instantiation dtype :: (linorder,\ldots,linorder) linorder}
\end{itemize}

All the non-recursive types that are used in the datatype must have similar instantiations.
For recursive type-dependencies this is automatically generated.

For example, for the \texttt{datatype tree = Leaf nat | Node "tree list"} we require that
@{type nat} is already in @{class linorder}, whereas for @{type list} nothing is required, since for the
\texttt{tree}
datatype the @{type list} is only used recursively.

However, if we define \texttt{datatype tree = Leaf "nat list" | Node tree tree} then
@{type list} must
provide the above instantiations.

Note that when calling the generator for @{class linorder}, it will automatically also derive the instantiations
for @{class order}, which in turn invokes the generator for @{class ord}.
A later invokation of @{class linorder}
after @{class order} or @{class ord} is not possible.
*}

subsection "Implementation Notes"

text {*
The generator uses the recursors from the datatype package to define a lexicographic order.
E.g., for a declaration
\texttt{datatype 'a tree = Empty | Node "'a tree" 'a "'a tree"}
this will semantically result in
\begin{verbatim}
(Empty < Node _ _ _) = True
(Node l1 l2 l3 < Node r1 r2 r3) =
  (l1 < r1 || l1 = r1 && (l2 < r2 || l2 = r2 && l3 < r3))
(_ < _) = False
(l <= r) = (l < r || l = r)
\end{verbatim}

The desired properties (like @{term "x < y \<Longrightarrow> y < z \<Longrightarrow> x < z"})
of the orders are all proven using induction (with the induction theorem from the datatype on @{term x}),
and afterwards there is a case distinction on the remaining variables, i.e., here @{term y} and @{term z}.
If the constructors of @{term x}, @{term y}, and @{term z} are different always some basic tactic is invoked.
In the other case (identical constructors) for each property a dedicated tactic was designed.
*}

subsection "Features and Limitations"

text {*
The order generator has been developed mainly for datatypes without explicit mutual recursion.
For mutual recursive datatypes---like
\texttt{datatype a = C b and b = D a a}---only
for the first mentioned datatype---here \texttt{a}---the instantiations of the order-classes are
derived.

Indirect recursion like in \texttt{datatype tree = Leaf nat | Node "tree list"} should work
without problems.
*}

subsection "Installing the generator"

lemma linear_cases: "(x :: 'a :: linorder) = y \<or> x < y \<or> y < x" by auto

ML_file "order_generator.ML"

setup {*
  Order_Generator.setup
*}

end