(* ========================================================================= *)
(* Arithmetization of syntax and Tarski's theorem.                           *)
(* ========================================================================= *)
prioritize_num();;
(* ------------------------------------------------------------------------- *)
(* This is to fake the fact that we might really be using strings.           *)
(* ------------------------------------------------------------------------- *)
let NUMBER_DENUMBER = prove
 (`(!s. denumber(number s) = s) /\
   (!n. number(denumber n) = n)`,
  REWRITE_TAC[number; denumber] THEN ONCE_REWRITE_TAC[
MULT_SYM] THEN
  SIMP_TAC[ARITH_RULE `x < 2 ==> (2 * y + x) DIV 2 = y`;
           
MOD_MULT_ADD; 
MOD_LT; GSYM 
DIVISION; 
ARITH_EQ;
           ARITH_RULE `1 - m < 2`; ARITH_RULE `x < 2 ==> 1 - (1 - x) = x`]);;
 
 
(* ------------------------------------------------------------------------- *)
(* Arithmetization.                                                          *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Injectivity.                                                              *)
(* ------------------------------------------------------------------------- *)
let GTERM_INJ = prove
 (`!s t. (gterm s = gterm t) <=> (s = t)`,
  MATCH_MP_TAC term_INDUCT THEN REPEAT CONJ_TAC THENL
   [ALL_TAC;
    GEN_TAC;
    GEN_TAC THEN DISCH_TAC;
    REPEAT GEN_TAC THEN STRIP_TAC;
    REPEAT GEN_TAC THEN STRIP_TAC] THEN
  MATCH_MP_TAC term_INDUCT THEN
  ASM_REWRITE_TAC[term_DISTINCT; term_INJ; gterm;
                  
NPAIR_INJ; 
NUMBER_INJ; 
ARITH_EQ]);;
 
 
let GFORM_INJ = prove
 (`!p q. (gform p = gform q) <=> (p = q)`,
  MATCH_MP_TAC form_INDUCT THEN REPEAT CONJ_TAC THENL
   [ALL_TAC;
    ALL_TAC;
    GEN_TAC THEN GEN_TAC;
    GEN_TAC THEN GEN_TAC;
    GEN_TAC THEN GEN_TAC;
    REPEAT GEN_TAC THEN STRIP_TAC;
    REPEAT GEN_TAC THEN STRIP_TAC;
    REPEAT GEN_TAC THEN STRIP_TAC;
    REPEAT GEN_TAC THEN STRIP_TAC;
    REPEAT GEN_TAC THEN STRIP_TAC;
    REPEAT GEN_TAC THEN STRIP_TAC;
    REPEAT GEN_TAC THEN STRIP_TAC] THEN
  MATCH_MP_TAC form_INDUCT THEN
  ASM_REWRITE_TAC[form_DISTINCT; form_INJ; gform; 
NPAIR_INJ; 
ARITH_EQ] THEN
  REWRITE_TAC[
GTERM_INJ; 
NUMBER_INJ]);;
 
 
(* ------------------------------------------------------------------------- *)
(* Useful case theorems.                                                     *)
(* ------------------------------------------------------------------------- *)
let GTERM_CASES = prove
 (`((gterm u = 
NPAIR 0 (number x)) <=> (u = V x)) /\
   ((gterm u = 
NPAIR 1 0) <=> (u = Z)) /\
   ((gterm u = 
NPAIR 2 n) <=> (?t. (u = Suc t) /\ (gterm t = n))) /\
   ((gterm u = 
NPAIR 3 (
NPAIR m n)) <=>
          (?s t. (u = s ++ t) /\ (gterm s = m) /\ (gterm t = n))) /\
   ((gterm u = 
NPAIR 4 (
NPAIR m n)) <=>
          (?s t. (u = s ** t) /\ (gterm s = m) /\ (gterm t = n)))`,
 
 
let GFORM_CASES = prove
 (`((gform r = 
NPAIR 0 0) <=> (r = False)) /\
   ((gform r = 
NPAIR 0 1) <=> (r = True)) /\
   ((gform r = 
NPAIR 1 (
NPAIR m n)) <=>
        (?s t. (r = s === t) /\ (gterm s = m) /\ (gterm t = n))) /\
   ((gform r = 
NPAIR 2 (
NPAIR m n)) <=>
        (?s t. (r = s << t) /\ (gterm s = m) /\ (gterm t = n))) /\
   ((gform r = 
NPAIR 3 (
NPAIR m n)) <=>
        (?s t. (r = s <<= t) /\ (gterm s = m) /\ (gterm t = n))) /\
   ((gform r = 
NPAIR 4 n) = (?p. (r = Not p) /\ (gform p = n))) /\
   ((gform r = 
NPAIR 5 (
NPAIR m n)) <=>
        (?p q. (r = p && q) /\ (gform p = m) /\ (gform q = n))) /\
   ((gform r = 
NPAIR 6 (
NPAIR m n)) <=>
        (?p q. (r = p || q) /\ (gform p = m) /\ (gform q = n))) /\
   ((gform r = 
NPAIR 7 (
NPAIR m n)) <=>
        (?p q. (r = p --> q) /\ (gform p = m) /\ (gform q = n))) /\
   ((gform r = 
NPAIR 8 (
NPAIR m n)) <=>
        (?p q. (r = p <-> q) /\ (gform p = m) /\ (gform q = n))) /\
   ((gform r = 
NPAIR 9 (
NPAIR (number x) n)) <=>
        (?p. (r = !!x p) /\ (gform p = n))) /\
   ((gform r = 
NPAIR 10 (
NPAIR (number x) n)) <=>
        (?p. (r = ??x p) /\ (gform p = n)))`,
 
 
(* ------------------------------------------------------------------------- *)
(* Definability of "godel number of numeral n".                              *)
(* ------------------------------------------------------------------------- *)
 FV_RTC; FV_GNUMERAL1]);;
 ARITH_PAIR; TERMVAL_NUMERAL] THEN
  REWRITE_TAC[termval; ARITH_EQ; o_THM; valmod] THEN
  MP_TAC(INST
   [`(gterm o numeral)`,`fn:num->num`;
    `3`,`e:num`;
    `\a:num b:num. NPAIR 2 a`,`f:num->num->num`] PRIMREC_SIGMA) THEN
  ANTS_TAC THENL
   [REWRITE_TAC[gterm; numeral; o_THM] THEN REWRITE_TAC[NPAIR; ARITH];
    SIMP_TAC[gnumeral; o_THM]]);;
 FVT_PAIR; FVT_NUMERAL]);;
(* ------------------------------------------------------------------------- *)
(* Diagonal substitution.                                                    *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Hence diagonalization of a predicate.                                     *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* And hence the fixed point.                                                *)
(* ------------------------------------------------------------------------- *)
let HOLDS_FIXPOINT = prove
 (`!x p v. holds v (fixpoint x p) <=>
           holds ((x |-> gform(fixpoint x p)) v) p`,
  REPEAT GEN_TAC THEN SIMP_TAC[fixpoint; holds; 
HOLDS_QDIAG] THEN
  SUBGOAL_THEN
   `((x |-> gform(diagonalize x p)) v) x = gform (diagonalize x p)`
  MP_TAC THENL [REWRITE_TAC[
VALMOD_BASIC]; ALL_TAC] THEN
  DISCH_THEN(fun th -> REWRITE_TAC[MATCH_MP 
ARITH_DIAGONALIZE th]) THEN
  REWRITE_TAC[
VALMOD_VALMOD_BASIC]);;
 
 
(* ------------------------------------------------------------------------- *)
(* Hence Tarski's theorem on the undefinability of truth.                    *)
(* ------------------------------------------------------------------------- *)