QuickSortが停止する事をあぐだくんに教えてあげたい
けれども、分かりません・・・。
module QSort where open import Data.List open import Data.Bool open import Data.Product data Nat : Set0 where zero : Nat succ : Nat -> Nat Length : {A : Set0} -> List A -> Nat Length [] = zero Length (x ∷ xs) = succ (Length xs) _<_ : Nat -> Nat -> Bool _ < zero = false zero < _ = true (succ a) < (succ b) = a < b filter1 : (Nat -> Bool) -> List Nat -> List Nat filter1 p [] = [] filter1 p (x ∷ xs) with p x | filter1 p xs ... | true | ys = (x ∷ ys) ... | false | ys = ys sort : List Nat -> List Nat sort [] = [] sort (x ∷ xs) = (sort first) ++ [ x ] ++ (sort last) where first : List Nat first = filter1 (λ v -> v < x) xs last : List Nat last = filter1 (λ v -> not (v < x)) xs
filter1は停止性が勝手に確認されるらしくて良いんですけれども、sortは一方そうは行かない感じです。
このプログラムを書く人間からしてみると
first = filter1 (λ v -> v < x) xs 'は' (x ∷ xs) 'よりも短い'
という事が分かっていて、lastも同様で、sortは元のリストより短いリストを作りそれに繰り返し適用していくので、いつかは再帰が止まるという事が分かります。
が、あぐだくんは何考えているのか知らないんですけれども、少なくともfilter1した結果が、filter1を適用したリストよりも小さくなる
filter1 (λ v -> v < x) xs <= xs
という事が分かって無いんじゃないかと思います。これが分からないと
filter1 (λ v -> v < x) xs <= xs かつ xs <= x ∷ xs したがって first = filter1 (λ v -> v < x) xs 'は' (x ∷ xs) 'よりも短い'
という事が言えません。
さて、そうしたらどうやって教えれば良いのかとかいう感じなんですけれども・・・。
色々
data NatPair : Nat -> Nat -> Set0 where nat_pair : (a : Nat) -> (b : Nat) -> NatPair a b LE : (a : Nat) -> (b : Nat) -> NatPair b b LE n m = ∃(x : Nat) . nat_pair (x + n) m
みたいなん出来ないかなー。
このLEが定義出来ると、LE (succ zero) zeroみたいな事は取りあえず出来なくなるので、それは制約につながってどうにかなってくれるかなーみたいな。