(************************************)
(* Lambda terms with marked redexes *)
(************************************)

Inductive redexes : Set :=
  | Var : nat -> redexes
  | Fun : redexes -> redexes
  | Ap : bool -> redexes -> redexes -> redexes.(************************************)
(* Lambda terms with marked redexes *)
(************************************)

Inductive redexes : Set :=
  | Var : nat -> redexes
  | Fun : redexes -> redexes
  | Ap : bool -> redexes -> redexes -> redexes.(************************************)
(* Lambda terms with marked redexes *)
(************************************)

Inductive redexes : Set :=
  | Var : nat -> redexes
  | Fun : redexes -> redexes
  | Ap : bool -> redexes -> redexes -> redexes.(************************************)
(* Lambda terms with marked redexes *)
(************************************)

Inductive redexes : Set :=
  | Var : nat -> redexes
  | Fun : redexes -> redexes
  | Ap : bool -> redexes -> redexes -> redexes.(* A redex is marked as (Ap true (Fun M) N) *)

(* The Boolean algebra of sets of redexes *)

Inductive sub : redexes -> redexes -> Prop :=
  | Sub_Var : forall n : nat, sub (Var n) (Var n)
  | Sub_Fun : forall U V : redexes, sub U V -> sub (Fun U) (Fun V)
  | Sub_Ap1 :
      forall U1 V1 : redexes,
      sub U1 V1 ->
      forall U2 V2 : redexes,
      sub U2 V2 -> forall b : bool, sub (Ap false U1 U2) (Ap b V1 V2)
  | Sub_Ap2 :
      forall U1 V1 : redexes,
      sub U1 V1 ->
      forall U2 V2 : redexes,
      sub U2 V2 -> forall b : bool, sub (Ap true U1 U2) (Ap true V1 V2).(* A redex is marked as (Ap true (Fun M) N) *)

(* The Boolean algebra of sets of redexes *)

Inductive sub : redexes -> redexes -> Prop :=
  | Sub_Var : forall n : nat, sub (Var n) (Var n)
  | Sub_Fun : forall U V : redexes, sub U V -> sub (Fun U) (Fun V)
  | Sub_Ap1 :
      forall U1 V1 : redexes,
      sub U1 V1 ->
      forall U2 V2 : redexes,
      sub U2 V2 -> forall b : bool, sub (Ap false U1 U2) (Ap b V1 V2)
  | Sub_Ap2 :
      forall U1 V1 : redexes,
      sub U1 V1 ->
      forall U2 V2 : redexes,
      sub U2 V2 -> forall b : bool, sub (Ap true U1 U2) (Ap true V1 V2).(* A redex is marked as (Ap true (Fun M) N) *)

(* The Boolean algebra of sets of redexes *)

Inductive sub : redexes -> redexes -> Prop :=
  | Sub_Var : forall n : nat, sub (Var n) (Var n)
  | Sub_Fun : forall U V : redexes, sub U V -> sub (Fun U) (Fun V)
  | Sub_Ap1 :
      forall U1 V1 : redexes,
      sub U1 V1 ->
      forall U2 V2 : redexes,
      sub U2 V2 -> forall b : bool, sub (Ap false U1 U2) (Ap b V1 V2)
  | Sub_Ap2 :
      forall U1 V1 : redexes,
      sub U1 V1 ->
      forall U2 V2 : redexes,
      sub U2 V2 -> forall b : bool, sub (Ap true U1 U2) (Ap true V1 V2).(* A redex is marked as (Ap true (Fun M) N) *)

(* The Boolean algebra of sets of redexes *)

Inductive sub : redexes -> redexes -> Prop :=
  | Sub_Var : forall n : nat, sub (Var n) (Var n)
  | Sub_Fun : forall U V : redexes, sub U V -> sub (Fun U) (Fun V)
  | Sub_Ap1 :
      forall U1 V1 : redexes,
      sub U1 V1 ->
      forall U2 V2 : redexes,
      sub U2 V2 -> forall b : bool, sub (Ap false U1 U2) (Ap b V1 V2)
  | Sub_Ap2 :
      forall U1 V1 : redexes,
      sub U1 V1 ->
      forall U2 V2 : redexes,
      sub U2 V2 -> forall b : bool, sub (Ap true U1 U2) (Ap true V1 V2).(* A redex is marked as (Ap true (Fun M) N) *)

(* The Boolean algebra of sets of redexes *)

Inductive sub : redexes -> redexes -> Prop :=
  | Sub_Var : forall n : nat, sub (Var n) (Var n)
  | Sub_Fun : forall U V : redexes, sub U V -> sub (Fun U) (Fun V)
  | Sub_Ap1 :
      forall U1 V1 : redexes,
      sub U1 V1 ->
      forall U2 V2 : redexes,
      sub U2 V2 -> forall b : bool, sub (Ap false U1 U2) (Ap b V1 V2)
  | Sub_Ap2 :
      forall U1 V1 : redexes,
      sub U1 V1 ->
      forall U2 V2 : redexes,
      sub U2 V2 -> forall b : bool, sub (Ap true U1 U2) (Ap true V1 V2).Definition bool_max (b b' : bool) :=
  match b return bool with
  | true => true
  | false => b'
  end.

Lemma max_false : forall b : bool, bool_max b false = b.