(* ========================================================================= *)
(* First order logic based on the language of arithmetic.                    *)
(* ========================================================================= *)
prioritize_num();;
(* ------------------------------------------------------------------------- *)
(* Syntax of terms.                                                          *)
(* ------------------------------------------------------------------------- *)
parse_as_infix("++",(20,"right"));;
parse_as_infix("**",(22,"right"));;
;
let term_DISTINCT = distinctness "term";;
let term_INJ = injectivity "term";;
(* ------------------------------------------------------------------------- *)
(* Syntax of formulas.                                                       *)
(* ------------------------------------------------------------------------- *)
parse_as_infix("===",(18,"right"));;
parse_as_infix("<<",(18,"right"));;
parse_as_infix("<<=",(18,"right"));;
parse_as_infix("&&",(16,"right"));;
parse_as_infix("||",(15,"right"));;
parse_as_infix("-->",(14,"right"));;
parse_as_infix("<->",(13,"right"));;
let form_INDUCT,form_RECURSION = define_type
  "form = False
        | True
        | === term term
        | << term term
        | <<= term term
        | Not form
        | && form form
        | || form form
        | --> form form
        | <-> form form
        | !! num form
        | ?? num form";let valmod = new_definition
  `(x |-> a) (v:A->B) = \y. if y = x then a else v(y)`;;
let VALMOD = prove
 (`!v x y a. ((x |-> y) v) a = if a = x then y else v(a)`,
 
let VALMOD_SWAP = prove
 (`!v x y a b.
     ~(x = y) ==> ((x |-> a) ((y |-> b) v) = (y |-> b) ((x |-> a) v))`,
 
let assign = new_definition
 `(x |=> a) = (x |-> a) V`;;
let ASSIGN = prove
 (`!x y a. (x |=> a) y = if y = x then a else V(y)`,
 
let FORMSUBST_EQ = prove
 (`!p i j. (!x. x 
IN FV(p) ==> (i(x) = j(x)))
           ==> (
formsubst i p = 
formsubst j p)`,
  MATCH_MP_TAC form_INDUCT THEN
  REWRITE_TAC[
FV; 
formsubst; 
IN_UNION; 
IN_DELETE] THEN
  SIMP_TAC[] THEN REWRITE_TAC[
CONJ_ASSOC] THEN
  GEN_REWRITE_TAC I [GSYM 
CONJ_ASSOC] THEN CONJ_TAC THENL
   [MESON_TAC[
TERMSUBST_EQ]; ALL_TAC] THEN
  CONJ_TAC THEN MAP_EVERY X_GEN_TAC [`x:num`; `p:form`] THEN
  (DISCH_TAC THEN MAP_EVERY X_GEN_TAC [`i:num->term`; `j:num->term`] THEN
   DISCH_TAC THEN REWRITE_TAC[
LET_DEF; 
LET_END_DEF; form_INJ] THEN
   MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN SIMP_TAC[] THEN
   CONJ_TAC THENL
    [ALL_TAC;
     DISCH_THEN(K ALL_TAC) THEN FIRST_ASSUM MATCH_MP_TAC THEN
     REWRITE_TAC[
valmod] THEN ASM_SIMP_TAC[]] THEN
   AP_THM_TAC THEN BINOP_TAC THENL
    [ASM_MESON_TAC[];
     AP_TERM_TAC THEN AP_TERM_TAC THEN FIRST_ASSUM MATCH_MP_TAC THEN
     REWRITE_TAC[
valmod] THEN ASM_MESON_TAC[]]));;