寫在Haskell,這裏是證明了一個列表是另一個置換的數據類型:可證明正確的置換小於爲O(n^2)
data Belongs (x :: k) (ys :: [k]) (zs :: [k]) where
BelongsHere :: Belongs x xs (x ': xs)
BelongsThere :: Belongs x xs xys -> Belongs x (y ': xs) (y ': xys)
data Permutation (xs :: [k]) (ys :: [k]) where
PermutationEmpty :: Permutation '[] '[]
PermutationCons :: Belongs x ys xys -> Permutation xs ys -> Permutation (x ': xs) xys
隨着Permutation
,我們現在可以置換記錄:
data Rec :: (u -> *) -> [u] -> * where
RNil :: Rec f '[]
(:&) :: !(f r) -> !(Rec f rs) -> Rec f (r ': rs)
insertRecord :: Belongs x ys zs -> f x -> Rec f ys -> Rec f zs
insertRecord BelongsHere v rs = v :& rs
insertRecord (BelongsThere b) v (r :& rs) = r :& insertRecord b v rs
permute :: Permutation xs ys -> Rec f xs -> Rec f ys
permute PermutationEmpty RNil = RNil
permute (PermutationCons b pnext) (r :& rs) = insertRecord b r (permute pnext rs)
這工作正常。然而,置換是O(n^2)
其中n
是記錄的長度。我想知道是否有一種方法可以通過使用不同的數據類型來表示排列來更快地實現它。
爲了比較,在一個可變的和非類型化設置(我知道是一個非常不同確實設置),我們可以在O(n)
及時申請置換,以這樣的異構記錄。您將記錄表示爲一組值並將排列表示爲一組新位置(不允許重複,且所有數字必須介於0和n之間)。應用排列只是迭代該數組並將這些位置索引到記錄的數組中。
我不指望O(n)
排列在更嚴格類型的設置中是可能的。但似乎O(n*log(n))
可能是可能的。我很感激任何反饋,並讓我知道是否需要澄清任何事情。另外,對此的回答可以使用Haskell,Agda或Idris,具體取決於與之交流的感覺。
在cs.stackexchange.com上問你可能會更好一些 –
我不經常使用這樣的解除代碼,因此無法推理上述問題,但我想知道是否有情況下GHC能夠檢查但在編譯時不會完全評估所有內容。 – jberryman
也許我們需要一個O(1)相關數組'Array [k]'來實現這一點。無論如何,在一個完全依賴的系統中,你將能夠保持排列(作爲一個位置數組)並且證明它與兩個列表相關。要應用排列,可以使用您提到的簡單O(n)算法。也許人們可以用GADT,類型級別的nats和單身。 – chi