Update from HH
[hl193./.git] / Arithmetic / pa.ml
1 (* ========================================================================= *)
2 (* Two interesting axiom systems: full Peano Arithmetic and Robinson's Q.    *)
3 (* ========================================================================= *)
4
5 (* ------------------------------------------------------------------------- *)
6 (* We define PA as an "inductive" predicate because the pattern-matching     *)
7 (* is a bit nicer, but of course we could just define the term explicitly.   *)
8 (* In effect, the returned PA_CASES would be our explicit definition.        *)
9 (*                                                                           *)
10 (* The induction axiom is done a little strangely in order to avoid using    *)
11 (* substitution as a primitive concept.                                      *)
12 (* ------------------------------------------------------------------------- *)
13
14 let PA_RULES,PA_INDUCT,PA_CASES = new_inductive_definition
15  `(!s. PA(Not (Z === Suc(s)))) /\
16   (!s t. PA(Suc(s) === Suc(t) --> s === t)) /\
17   (!t. PA(t ++ Z === t)) /\
18   (!s t. PA(s ++ Suc(t) === Suc(s ++ t))) /\
19   (!t. PA(t ** Z === Z)) /\
20   (!s t. PA(s ** Suc(t) === s ** t ++ s)) /\
21   (!p i j. ~(j IN FV(p))
22            ==> PA
23                 ((??i (V i === Z && p)) &&
24                  (!!j (??i (V i === V j && p)
25                            --> ??i (V i === Suc(V j) && p)))
26                  --> !!i p))`;;
27
28 let PA_SOUND = prove
29  (`!A p. (!a. a IN A ==> true a) /\ (PA UNION A) |-- p ==> true p`,
30   REPEAT STRIP_TAC THEN MATCH_MP_TAC THEOREMS_TRUE THEN
31   EXISTS_TAC `PA UNION A` THEN
32   ASM_SIMP_TAC[IN_UNION; TAUT `(a \/ b ==> c) <=> (a ==> c) /\ (b ==> c)`] THEN
33   REWRITE_TAC[IN] THEN MATCH_MP_TAC PA_INDUCT THEN
34   REWRITE_TAC[true_def; holds; termval] THEN
35   REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL
36    [SIMP_TAC[ADD_CLAUSES; MULT_CLAUSES; EXP; SUC_INJ; NOT_SUC] THEN ARITH_TAC;
37     ALL_TAC] THEN
38   MAP_EVERY X_GEN_TAC [`q:form`; `i:num`; `j:num`] THEN
39   ASM_CASES_TAC `j:num = i` THEN
40   ASM_REWRITE_TAC[VALMOD; VALMOD_VALMOD_BASIC] THEN
41   SIMP_TAC[HOLDS_VALMOD_OTHER] THENL [MESON_TAC[]; ALL_TAC] THEN
42   REWRITE_TAC[UNWIND_THM2] THEN DISCH_TAC THEN
43   SUBGOAL_THEN
44    `!a b v. holds ((i |-> a) ((j |-> b) v)) q <=> holds ((i |-> a) v) q`
45    (fun th -> REWRITE_TAC[th])
46   THENL
47    [REPEAT STRIP_TAC THEN MATCH_MP_TAC HOLDS_VALUATION THEN
48     ASM_REWRITE_TAC[valmod] THEN ASM_MESON_TAC[];
49     GEN_TAC THEN STRIP_TAC THEN INDUCT_TAC THEN ASM_SIMP_TAC[]]);;
50
51 (* ------------------------------------------------------------------------- *)
52 (* Robinson's axiom system Q.                                                *)
53 (*                                                                           *)
54 (*  <<(forall m n. S(m) = S(n) ==> m = n) /\                                 *)
55 (*    (forall n. ~(n = 0) <=> exists m. n = S(m)) /\                         *)
56 (*    (forall n. 0 + n = n) /\                                               *)
57 (*    (forall m n. S(m) + n = S(m + n)) /\                                   *)
58 (*    (forall n. 0 * n = 0) /\                                               *)
59 (*    (forall m n. S(m) * n = n + m * n) /\                                  *)
60 (*    (forall m n. m <= n <=> exists d. m + d = n) /\                        *)
61 (*    (forall m n. m < n <=> S(m) <= n)>>;;                                  *)
62 (* ------------------------------------------------------------------------- *)
63
64 let robinson = new_definition
65  `robinson =
66         (!!0 (!!1 (Suc(V 0) === Suc(V 1) --> V 0 === V 1))) &&
67         (!!1 (Not(V 1 === Z) <-> ??0 (V 1 === Suc(V 0)))) &&
68         (!!1 (Z ++ V 1 === V 1)) &&
69         (!!0 (!!1 (Suc(V 0) ++ V 1 === Suc(V 0 ++ V 1)))) &&
70         (!!1 (Z ** V 1 === Z)) &&
71         (!!0 (!!1 (Suc(V 0) ** V 1 === V 1 ++ V 0 ** V 1))) &&
72         (!!0 (!!1 (V 0 <<= V 1 <-> ??2 (V 0 ++ V 2 === V 1)))) &&
73         (!!0 (!!1 (V 0 << V 1 <-> Suc(V 0) <<= V 1)))`;;