playground/coq/unfinished/hanoi.v

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.