1 (* ========================================================================= *)
2 (* Iterated application of a function, ITER n f x = f^n(x). *)
4 (* (c) Marco Maggesi, Graziano Gentili and Gianni Ciolli, 2008. *)
5 (* ========================================================================= *)
8 `(!f. ITER 0 f x = x) /\
9 (!f n. ITER (SUC n) f x = f (ITER n f x))`;;
11 let ITER_POINTLESS = prove
12 (`(!f. ITER 0 f = I) /\
13 (!f n. ITER (SUC n) f = f o ITER n f)`,
14 REWRITE_TAC [FUN_EQ_THM; I_THM; o_THM; ITER]);;
17 (`(!f x. ITER 0 f x = x) /\
18 (!f n x. ITER (SUC n) f x = ITER n f (f x))`,
19 REWRITE_TAC [ITER] THEN GEN_TAC THEN INDUCT_TAC THEN
20 ASM_REWRITE_TAC [ITER]);;
22 let ITER_ALT_POINTLESS = prove
23 (`(!f. ITER 0 f = I) /\
24 (!f n. ITER (SUC n) f = ITER n f o f)`,
25 REWRITE_TAC [FUN_EQ_THM; I_THM; o_THM; ITER_ALT]);;
28 (`!f x. ITER 1 f x = f x`,
29 REWRITE_TAC[num_CONV `1`; ITER]);;
32 (`!f n m x. ITER n f (ITER m f x) = ITER (n + m) f x`,
33 GEN_TAC THEN INDUCT_TAC THEN ASM_REWRITE_TAC[ITER; ADD]);;
36 (`!f n m x. ITER n (ITER m f) x = ITER (n * m) f x`,
37 GEN_TAC THEN INDUCT_TAC THEN
38 ASM_REWRITE_TAC[ITER; MULT; ITER_ADD; ADD_AC]);;
40 let ITER_FIXPOINT = prove
41 (`!f n x. f x = x ==> ITER n f x = x`,
42 GEN_TAC THEN INDUCT_TAC THEN ASM_SIMP_TAC [ITER_ALT]);;
44 (* ------------------------------------------------------------------------- *)
45 (* Existence of "order" or "characteristic" in a general setting. *)
46 (* ------------------------------------------------------------------------- *)
48 let ORDER_EXISTENCE_GEN = prove
50 P(f 0) /\ (!m n. P(f m) /\ ~(m = 0) ==> (P(f(m + n)) <=> P(f n)))
51 ==> ?d. !n. P(f n) <=> d divides n`,
53 ASM_CASES_TAC `!n. ~(n = 0) ==> ~P(f n:A)` THENL
54 [EXISTS_TAC `0` THEN REWRITE_TAC[NUMBER_RULE `0 divides n <=> n = 0`] THEN
56 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM])] THEN
57 GEN_REWRITE_TAC LAND_CONV [num_WOP] THEN MATCH_MP_TAC MONO_EXISTS THEN
58 X_GEN_TAC `d:num` THEN REWRITE_TAC[NOT_IMP] THEN
59 REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN STRIP_TAC THEN
60 MATCH_MP_TAC num_WF THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
61 ASM_CASES_TAC `n = 0` THENL
62 [ASM_MESON_TAC[NUMBER_RULE `n divides 0`]; ALL_TAC] THEN
63 ASM_CASES_TAC `d <= n:num` THENL
64 [ALL_TAC; ASM_MESON_TAC[NOT_LT; DIVIDES_LE]] THEN
65 SUBGOAL_THEN `n:num = (n - d) + d` SUBST1_TAC THENL
66 [ASM_ARITH_TAC; ABBREV_TAC `m:num = n - d`] THEN
67 REWRITE_TAC[NUMBER_RULE `d divides m + d <=> d divides m`] THEN
68 FIRST_X_ASSUM(MP_TAC o SPEC `m:num`) THEN
69 ANTS_TAC THENL [ASM_ARITH_TAC; ASM_MESON_TAC[ADD_SYM]]);;
71 let ORDER_EXISTENCE_ITER = prove
74 (!x y. R x y ==> R y x) /\
75 (!x y z. R x y /\ R y z ==> R x z) /\
76 (!x y. R x y ==> R (f x) (f y))
77 ==> ?d. !n. R (ITER n f z) z <=> d divides n`,
79 MP_TAC(ISPECL [`\x. (R:A->A->bool) x z`;
80 `\n. ITER n f (z:A)`] ORDER_EXISTENCE_GEN) THEN
81 ASM_REWRITE_TAC[ITER] THEN DISCH_THEN MATCH_MP_TAC THEN
82 REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN X_GEN_TAC `m:num` THEN STRIP_TAC THEN
83 ONCE_REWRITE_TAC[ADD_SYM] THEN REWRITE_TAC[GSYM ITER_ADD] THEN
85 `!a b:num->A. (!x y. R x y ==> R y x) /\
86 (!x y z. R x y /\ R y z ==> R x z) /\
88 ==> (!n. R (a n) z <=> R (b n) z)`) THEN
89 DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN
90 INDUCT_TAC THEN ASM_REWRITE_TAC[ITER] THEN
93 let ORDER_EXISTENCE_CARD = prove
95 FINITE { R(ITER n f z) | n IN (:num)} /\
96 CARD { R(ITER n f z) | n IN (:num)} <= k /\
98 (!x y. R x y ==> R y x) /\
99 (!x y z. R x y /\ R y z ==> R x z) /\
100 (!x y. R (f x) (f y) <=> R x y)
101 ==> ?d. 0 < d /\ d <= k /\ !n. R (ITER n f z) z <=> d divides n`,
102 REPEAT STRIP_TAC THEN
104 `?m. 0 < m /\ m <= k /\ (R:A->A->bool) (ITER m f z) z`
105 STRIP_ASSUME_TAC THENL
106 [MP_TAC(ISPECL [`\n. (R:A->A->bool) (ITER n f z)`; `0..k`]
107 CARD_IMAGE_EQ_INJ) THEN
108 REWRITE_TAC[FINITE_NUMSEG; CARD_NUMSEG; SUB_0] THEN
109 MATCH_MP_TAC(TAUT `~p /\ (~q ==> r) ==> (p <=> q) ==> r`) THEN
111 [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (ARITH_RULE
112 `c <= k ==> s <= c ==> ~(s = k + 1)`)) THEN
113 MATCH_MP_TAC CARD_SUBSET THEN ASM_REWRITE_TAC[] THEN ASM SET_TAC[];
114 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; LEFT_IMP_EXISTS_THM] THEN
115 MATCH_MP_TAC WLOG_LT THEN REWRITE_TAC[] THEN
116 CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
117 MAP_EVERY X_GEN_TAC [`p:num`; `q:num`] THEN
118 REWRITE_TAC[IN_NUMSEG] THEN REPEAT STRIP_TAC THEN
119 EXISTS_TAC `q - p:num` THEN
120 REPEAT(CONJ_TAC THENL [ASM_ARITH_TAC; ALL_TAC]) THEN
123 ==> (R:A->A->bool) (ITER (p - d) f z) (ITER (q - d) f z)`
125 [INDUCT_TAC THEN ASM_REWRITE_TAC[SUB_0] THENL
126 [SPEC_TAC(`q:num`,`q:num`) THEN INDUCT_TAC THEN
127 ASM_REWRITE_TAC[ITER];
128 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN
129 ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
130 SUBGOAL_THEN `q - d = SUC(q - SUC d) /\ p - d = SUC(p - SUC d)`
131 (fun th -> REWRITE_TAC[th]) THENL [ASM_ARITH_TAC; ALL_TAC] THEN
132 ASM_REWRITE_TAC[ITER]];
133 DISCH_THEN(MP_TAC o SPEC `p:num`) THEN
134 REWRITE_TAC[LE_REFL; SUB_REFL; ITER] THEN ASM_MESON_TAC[]]];
135 MP_TAC(ISPECL [`R:A->A->bool`; `f:A->A`; `z:A`] ORDER_EXISTENCE_ITER) THEN
136 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN
137 X_GEN_TAC `d:num` THEN ASM_CASES_TAC `d = 0` THEN ASM_SIMP_TAC[] THEN
138 DISCH_THEN(MP_TAC o SPEC `m:num`) THEN
139 ASM_SIMP_TAC[LE_1; NUMBER_RULE `!n. 0 divides n <=> n = 0`] THEN
140 DISCH_THEN(MP_TAC o MATCH_MP DIVIDES_LE) THEN ASM_ARITH_TAC]);;
142 let ORDER_EXISTENCE_FINITE = prove
144 FINITE { R(ITER n f z) | n IN (:num)} /\
146 (!x y. R x y ==> R y x) /\
147 (!x y z. R x y /\ R y z ==> R x z) /\
148 (!x y. R (f x) (f y) <=> R x y)
149 ==> ?d. 0 < d /\ !n. R (ITER n f z) z <=> d divides n`,
150 REPEAT STRIP_TAC THEN
151 MP_TAC(ISPECL [`R:A->A->bool`; `f:A->A`; `z:A`;
152 `CARD {(R:A->A->bool)(ITER n f z) | n IN (:num)}`]
153 ORDER_EXISTENCE_CARD) THEN ASM_REWRITE_TAC[LE_REFL] THEN MESON_TAC[]);;