(* ========================================================================= *)
(* Church-Rosser property for combinatory logic (S and K combinators). *)
(* *)
(* This is adapted from a HOL4 develoment, itself derived from an old HOL88 *)
(* example by Tom Melham and Juanito Camilleri. For a detailed discussion, *)
(* see pp. 29-39 of the following paper: *)
(* *)
(* http://www.comlab.ox.ac.uk/tom.melham/pub/Camilleri-1992-RID.pdf *)
(* ========================================================================= *)
needs "Examples/reduct.ml";;
(* ------------------------------------------------------------------------- *)
(* Definition of confluence. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Basic term structure: S and K combinators and function application ("%"). *)
(* ------------------------------------------------------------------------- *)
parse_as_infix("%",(20,"left"));;
;
(* ------------------------------------------------------------------------- *)
(* Reduction relation. *)
(* ------------------------------------------------------------------------- *)
parse_as_infix("-->",(12,"right"));;
let redn_rules, redn_ind, redn_cases = new_inductive_definition
`(!x y f. x --> y ==> f % x --> f % y) /\
(!f g x. f --> g ==> f % x --> g % x) /\
(!x y. K % x % y --> x) /\
(!f g x. S % f % g % x --> (f % x) % (g % x))`;;
(* ------------------------------------------------------------------------- *)
(* A different, "parallel", reduction relation. *)
(* ------------------------------------------------------------------------- *)
parse_as_infix("-||->",(12,"right"));;
let predn_rules, predn_ind, predn_cases = new_inductive_definition
`(!x. x -||-> x) /\
(!x y u v. x -||-> y /\ u -||-> v ==> x % u -||-> y % v) /\
(!x y. K % x % y -||-> x) /\
(!f g x. S % f % g % x -||-> (f % x) % (g % x))`;;
(* ------------------------------------------------------------------------- *)
(* Abbreviations for their reflexive-transitive closures. *)
(* ------------------------------------------------------------------------- *)
parse_as_infix("-->*",(12,"right"));;
parse_as_infix("-||->*",(12,"right"));;
let RTCredn_rules = REWRITE_RULE[SYM RTCredn] (ISPEC `(-->)` RTC_RULES);;
let RTCredn_ind = REWRITE_RULE[SYM RTCredn] (ISPEC `(-->)` RTC_INDUCT);;
let RTCpredn_rules = REWRITE_RULE[SYM RTCpredn] (ISPEC `(-||->)` RTC_RULES);;
let RTCpredn_ind = REWRITE_RULE[SYM RTCpredn] (ISPEC `(-||->)` RTC_INDUCT);;
(* ------------------------------------------------------------------------- *)
(* Prove that the two RTCs are actually the same. *)
(* ------------------------------------------------------------------------- *)
let RTCredn_ap_monotonic = prove
(`!x y. x -->* y ==> !z. x % z -->* y % z /\ z % x -->* z % y`,
MATCH_MP_TAC RTCredn_ind THEN MESON_TAC[RTCredn_rules; redn_rules]);;
(* ------------------------------------------------------------------------- *)
(* Now prove diamond property for "-||->" reduction. *)
(* ------------------------------------------------------------------------- *)
let characterise t =
SIMP_RULE[distinctness "cl"; injectivity "cl"; GSYM EXISTS_REFL;
RIGHT_EXISTS_AND_THM; GSYM CONJ_ASSOC; UNWIND_THM1]
(SPEC t predn_cases);;
let Sx_PREDN = prove
(`!x y. S % x -||-> y <=> ?z. y = S % z /\ x -||-> z`,
REWRITE_TAC[characterise `S % x`] THEN
MESON_TAC[predn_rules; characterise `S`]);;
let Kx_PREDN = prove
(`!x y. K % x -||-> y <=> ?z. y = K % z /\ x -||-> z`,
REWRITE_TAC[characterise `K % x`] THEN
MESON_TAC[predn_rules; characterise `K`]);;
let Kxy_PREDN = prove
(`!x y z. K % x % y -||-> z <=>
(?u v. z = K % u % v /\ x -||-> u /\ y -||-> v) \/ z = x`,
REWRITE_TAC[characterise `K % x % y`] THEN
MESON_TAC[predn_rules;
Kx_PREDN]);;
let Sxy_PREDN = prove
(`!x y z. S % x % y -||-> z <=>
?u v. z = S % u % v /\ x -||-> u /\ y -||-> v`,
REWRITE_TAC[characterise `S % x % y`] THEN
MESON_TAC[predn_rules; characterise `S`;
Sx_PREDN]);;
let Sxyz_PREDN = prove
(`!w x y z. S % w % x % y -||-> z <=>
(?p q r. z = S % p % q % r /\
w -||-> p /\ x -||-> q /\ y -||-> r) \/
z = (w % y) % (x % y)`,
REWRITE_TAC[characterise `S % w % x % y`] THEN
MESON_TAC[predn_rules;
Sxy_PREDN]);;
let predn_diamond_lemma = prove
(`!x y. x -||-> y ==> !z. x -||-> z ==> ?u. y -||-> u /\ z -||-> u`,
ONCE_REWRITE_TAC[TAUT `a ==> b <=> a ==> a /\ b`] THEN
MATCH_MP_TAC predn_ind THEN SIMP_TAC[predn_rules] THEN REPEAT CONJ_TAC THENL
[MESON_TAC[predn_rules];
REPEAT STRIP_TAC THEN UNDISCH_THEN `x % u -||-> z`
(STRIP_ASSUME_TAC o SIMP_RULE[characterise `x % y`]) THENL
[ASM_MESON_TAC[predn_rules];
ASM_MESON_TAC[predn_rules];
SUBGOAL_THEN `?w. y = K % w /\ z -||-> w` MP_TAC;
SUBGOAL_THEN `?p q. y = S % p % q /\ f -||-> p /\ g -||-> q` MP_TAC] THEN
ASM_MESON_TAC[
Kx_PREDN;
Sxy_PREDN; predn_rules];
REWRITE_TAC[
Kxy_PREDN] THEN MESON_TAC[predn_rules];
REWRITE_TAC[
Sxyz_PREDN] THEN MESON_TAC[predn_rules]]);;
(* ------------------------------------------------------------------------- *)
(* Hence we have confluence of the main reduction. *)
(* ------------------------------------------------------------------------- *)