(* ========================================================================= *)
(* Derived properties of provability.                                        *)
(* ========================================================================= *)
(* ------------------------------------------------------------------------- *)
(* The primitive basis, separated into its named components.                 *)
(* ------------------------------------------------------------------------- *)
let axiom_funcong = prove
 (`(!A s t. A |-- s === t --> Suc s === Suc t) /\
   (!A s t u v. A |-- s === t --> u === v --> s ++ u === t ++ v) /\
   (!A s t u v. A |-- s === t --> u === v --> s ** u === t ** v)`,
 
let axiom_predcong = prove
 (`(!A s t u v. A |-- s === t --> u === v --> s === u --> t === v) /\
   (!A s t u v. A |-- s === t --> u === v --> s << u --> t << v) /\
   (!A s t u v. A |-- s === t --> u === v --> s <<= u --> t <<= v)`,
 
let imp_trans2 = prove
 (`!A p q r s. A |-- p --> q --> r /\ A |-- r --> s ==> A |-- p --> q --> s`,
 
let imp_true_rule = prove
 (`!A p q r. A |-- (p --> False) --> r /\ A |-- q --> r
             ==> A |-- (p --> q) --> r`,
 
let genimp = prove
 (`!x p q. A |-- p --> q ==> A |-- (!!x p) --> (!!x q)`,
 
let eximp = prove
 (`!x p q. A |-- p --> q ==> A |-- (??x p) --> (??x q)`,
 
let subspec = prove
 (`!A x t p q. ~(x 
IN FVT(t)) /\ ~(x 
IN FV(q)) /\ A |-- V x === t --> p --> q
               ==> A |-- (!!x p) --> q`,
 
let subalpha = prove
 (`!A x y p q. ((x = y) \/ ~(x 
IN FV(q)) /\ ~(y 
IN FV(p))) /\
               A |-- V x === V y --> p --> q
               ==> A |-- (!!x p) --> (!!y q)`,
  REPEAT GEN_TAC THEN ASM_CASES_TAC `x = y:num` THEN ASM_REWRITE_TAC[] THEN
  STRIP_TAC THENL
   [FIRST_X_ASSUM SUBST_ALL_TAC THEN
    ASM_MESON_TAC[
genimp; 
modusponens; 
axiom_eqrefl];
    ALL_TAC] THEN
  MATCH_MP_TAC 
gen_right THEN ASM_REWRITE_TAC[
FV; 
IN_DELETE] THEN
  MATCH_MP_TAC 
subspec THEN EXISTS_TAC `V y` THEN
  ASM_REWRITE_TAC[
FVT; 
IN_SING]);;