-- Lecture 4; Example 4: Equivalence of Reverses -- page 23 mod! BASIC-LIST(X :: TRIV) { [Empty NeList < List] op nil : -> Empty op _::_ : Elt List -> NeList } view t2n from TRIV to NAT{ sort Elt -> Nat } mod! LIST-@ { pr(BASIC-LIST) op _@_ : List List -> List var E : Elt . vars L1 L2 : List . eq nil @ L1 = L1 . eq (E :: L1) @ L2 = E :: (L1 @ L2) . } mod! LIST-@-assoc { pr(LIST-@) op _@_ : List List -> List {assoc} } mod! LIST-rev { pr(LIST-@-assoc) op rev _ : List -> List var E : Elt . var L : List . eq rev nil = nil . eq rev (E :: L) = (rev L) @ (E :: nil) . } select LIST-rev(t2n) red rev (0 :: 1 :: 2 :: nil) . -- page 24 select LIST-rev(t2n) -- You can see in the result of the reduction command -- how much rewrite steps it is reduced in. -- like (0.000 sec for parse, 55 rewrites(0.000 sec), 100 matches) red rev (1 :: nil) . -- 3 steps red rev (1 :: 2 :: nil) . -- 6 steps red rev (1 :: 2 :: 3 :: nil) . -- 10 steps red rev (1 :: 2 :: 3 :: 4 :: nil) . -- 15 steps red rev (1 :: 2 :: 3 :: 4 :: 5 :: nil) . -- 21 steps red rev (1 :: 2 :: 3 :: 4 :: 5 :: 6 :: nil) . -- 28 steps red rev (1 :: 2 :: 3 :: 4 :: 5 :: 6 :: 7 :: nil) . -- 36 steps red rev (1 :: 2 :: 3 :: 4 :: 5 :: 6 :: 7 :: 8 :: nil) . -- 45 steps red rev (1 :: 2 :: 3 :: 4 :: 5 :: 6 :: 7 :: 8 :: 9 :: nil) . -- 55 steps red rev (1 :: 2 :: 3 :: 4 :: 5 :: 6 :: 7 :: 8 :: 9 :: 10 :: nil) . -- 66 steps -- page 25 mod! LIST-revi { pr(BASIC-LIST) op revi : List List -> List vars L1 L2 : List var E : Elt eq revi(nil, L2) = L2 . eq revi((E :: L1), L2) = revi(L1, (E :: L2)) . } -- page 26 select LIST-revi(t2n) . set trace whole on red revi (0 :: 1 :: 2 :: 3 :: 4 :: 5 :: nil, nil) . set trace whole off -- page 27 -- PROVE revi (L, nil) = rev L open LIST-rev + LIST-revi + EQL . var E : Elt . op l : -> List . red revi(nil, nil) = rev nil . eq revi(l, nil) = rev l . red revi(E :: l, nil) = rev (E :: l) . close -- page 28 -- Lemma discovery fails into an infinite loop -- PROVE revi (L, nil) = rev L open LIST-rev + LIST-revi + EQL . var E : Elt . op l : -> List . red revi(nil, nil) = rev nil . eq revi(l, nil) = rev l . red revi(E :: l, nil) = rev (E :: l) . close -- PROVE revi(l, E :: nil) = (rev l) @ (E :: nil) open LIST-rev + LIST-revi + EQL . vars E F : Elt . op l : -> List . red revi(nil, E :: nil)= (rev nil) @ (E :: nil) . eq revi(l, E :: nil)= (rev l) @ (E :: nil) . red revi(F :: l, E :: nil)= (rev (F :: l)) @ (E :: nil) . close -- PROVE revi(l, F :: E :: nil) = (rev l) @ (F :: E :: nil) open LIST-rev + LIST-revi + EQL . vars E F G : Elt . op l : -> List . red revi(nil, F :: E :: nil)= (rev nil) @ (F :: E :: nil) . eq revi(l, F :: E :: nil)= (rev l) @ (F :: E :: nil) . red revi(G :: l, F :: E :: nil)= (rev (G :: l)) @ (F :: E :: nil) . close -- page 30 -- Prove Lemma rev L @ L' = revi(L, L') open LIST-rev + LIST-revi + EQL . var E : Elt . var L' : List . op l : -> List . red (rev nil) @ L' = revi(nil, L') . eq revi(l, L') = (rev l) @ L' . red (rev (E :: l)) @ L' = revi(E :: l, L') . close -- page 31 -- Adding Lemma rev L @ L' = revi(L, L') open LIST-rev + LIST-revi + EQL . var E : Elt . vars L L' : List eq revi(L, L') = (rev L) @ L' . op l : -> List . red revi(nil, nil) = rev nil . eq revi(l, nil) = rev l . red revi(E :: l, nil) = rev (E :: l) . close -- page 33 -- Proof score with comments -- Proof of revi(L, nil) = rev L open LIST-rev + LIST-revi + EQL . -- Declare Lemma eq revi(L:List, L¡Æ:List) = (rev L) @ L¡Æ . -- Declare an arbitrary element for Induction op l : -> List . --> Prove Induction Base red revi(nil, nil) = rev nil . -- Declare Induction Hypothesis eq revi(l, nil) = rev l . --> Prove Induction Step red revi(E:Elt :: l, nil) = rev (E :: l) . close