128 lines
3.5 KiB
Coq
128 lines
3.5 KiB
Coq
Require Import List.
|
|
Import ListNotations.
|
|
|
|
Fixpoint hanoi (n:nat) (start via final:nat) : list (nat*nat) :=
|
|
match n with
|
|
| O => []
|
|
| S n' => (hanoi n' start final via) ++ [(start, final)] ++
|
|
(hanoi n' via final start)
|
|
end.
|
|
Compute hanoi 3 0 1 2.
|
|
(* = [(0, 2); (0, 1); (2, 0); (0, 2); (1, 2); (1, 0); (2, 1)]
|
|
: list (nat * nat) *)
|
|
Compute hanoi 4 0 1 2.
|
|
Compute length (hanoi 5 0 1 2). (* 31 : nat *)
|
|
|
|
|
|
|
|
(************************************************************************)
|
|
|
|
(* 2ⁿ - 1 *)
|
|
|
|
(* N=3 => 7 moves
|
|
[[3,2,1], [], []]
|
|
[[3,2], [], [1]]
|
|
[[3], [2], [1]]
|
|
[[3], [2,1], []]
|
|
[[], [2,1], [3]]
|
|
[[1], [2], [3]]
|
|
[[1], [], [3,2]]
|
|
[[], [], [3,2,1]]
|
|
*)
|
|
|
|
|
|
(* N=4 => 15 moves
|
|
[[4,3,2,1], [], []]
|
|
[[4,3,2], [1], []]
|
|
[[4,3], [1], [2]]
|
|
[[4,3], [], [2,1]]
|
|
[[4], [3], [2,1]]
|
|
[[4,1], [3], [2]]
|
|
[[4,1], [3,2], []]
|
|
[[4], [3,2,1], []]
|
|
[[], [3,2,1], [4]]
|
|
[[], [3,2], [4,1]]
|
|
[[2], [3], [4,1]]
|
|
[[2,1], [3], [4]]
|
|
[[2,1], [], [4,3]]
|
|
[[2], [1], [4,3]]
|
|
[[], [1], [4,3,2]]
|
|
[[], [], [4,3,2,1]]
|
|
*)
|
|
|
|
Require Import List.
|
|
Import ListNotations.
|
|
|
|
(*
|
|
Inductive moves : list (list nat) -> Set :=
|
|
| A2B : forall (a b:nat) (aa bs cs:list nat),
|
|
a < b -> moves [a::aa; b::bs; cs] -> moves [aa; a::b::bs; cs]
|
|
| A2C : forall (a c:nat) (aa bs cs:list nat),
|
|
a < c -> moves [a::aa; bs; c::cs] -> moves [aa; bs; a::c::cs]
|
|
| B2A : forall (a b:nat) (aa bs cs:list nat),
|
|
b < a -> moves [a::aa; b::bs; cs] -> moves [b::a::aa; bs; cs]
|
|
| B2C : forall (b c:nat) (aa bs cs:list nat),
|
|
b < c -> moves [aa; b::bs; c::cs] -> moves [aa; bs; b::c::cs]
|
|
| C2A : forall (a c:nat) (aa bs cs:list nat),
|
|
c < a -> moves [a::aa; bs; c::cs] -> moves [c::a::aa; bs; cs]
|
|
| C2B : forall (b c:nat) (aa bs cs:list nat),
|
|
c < b -> moves [aa; b::bs; c::cs] -> moves [aa; c::b::bs; cs].
|
|
*)
|
|
|
|
(*
|
|
| A2BNil : forall (a:nat) (aa cc:list nat),
|
|
moves [a::aa; []; cc]
|
|
-> moves [aa; [List.last (a::aa) a]; cc]
|
|
*)
|
|
|
|
Compute (
|
|
match [1;2;3;4] with
|
|
| h::aa::x::nil => x
|
|
| _ => 0
|
|
end).
|
|
|
|
Check List.last.
|
|
Inductive moves : list (list nat) -> Set :=
|
|
| A2BNil : forall (a:nat) (aa cc:list nat),
|
|
moves [a::aa::nil; []; cc]
|
|
-> moves [aa; [List.last (a::aa) a]; cc]
|
|
| A2CNil : forall (a:nat) (aa bb:list nat),
|
|
moves [a::aa; bb; []] -> moves [aa; bb; [a]]
|
|
| B2ANil : forall (b:nat) (bb cc:list nat),
|
|
moves [[]; b::bb; cc] -> moves [[b]; bb; cc]
|
|
| B2CNil : forall (b:nat) (aa bb:list nat),
|
|
moves [aa; b::bb; []] -> moves [aa; bb; [b]]
|
|
| C2ANil : forall (c:nat) (bb cc:list nat),
|
|
moves [[]; bb; c::cc] -> moves [[c]; bb; cc]
|
|
| C2BNil : forall (c:nat) (aa cc:list nat),
|
|
moves [aa; []; c::cc] -> moves [aa; [c]; cc]
|
|
| A2B : forall (a b:nat) (aa bb cc:list nat),
|
|
a < b -> moves [a::aa; b::bb; cc] -> moves [aa; a::b::bb; cc]
|
|
| A2C : forall (a c:nat) (aa bb cc:list nat),
|
|
a < c -> moves [a::aa; bb; c::cc] -> moves [aa; bb; a::c::cc]
|
|
| B2A : forall (a b:nat) (aa bb cc:list nat),
|
|
b < a -> moves [a::aa; b::bb; cc] -> moves [b::a::aa; bb; cc]
|
|
| B2C : forall (b c:nat) (aa bb cc:list nat),
|
|
b < c -> moves [aa; b::bb; c::cc] -> moves [aa; bb; b::c::cc]
|
|
| C2A : forall (a c:nat) (aa bb cc:list nat),
|
|
c < a -> moves [a::aa; bb; c::cc] -> moves [c::a::aa; bb; cc]
|
|
| C2B : forall (b c:nat) (aa bb cc:list nat),
|
|
c < b -> moves [aa; b::bb; c::cc] -> moves [aa; c::b::bb; cc].
|
|
|
|
|
|
|
|
Lemma foo : moves [[3;2;1];[];[]] -> moves [[];[];[3;2;1]].
|
|
Proof.
|
|
intro H.
|
|
Check A2BNil.
|
|
Check A2BNil 3 _ _ H.
|
|
Compute A2BNil 3 _ _ H.
|
|
apply (A2BNil 3 _ _ H).
|
|
apply (A2B H).
|
|
moves [[3;2;1];[];[]].
|
|
Qed.
|
|
|
|
|
|
Check moves [[];[];[]].
|
|
Require Import Permutation.
|