-- |
{-# LANGUAGE  GeneralizedNewtypeDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE  MultiParamTypeClasses #-}


module Talash.ScoredMatch (ChunkIndex (..) , ScoredMatchSized (..) , emptyMatch) where

import Talash.Intro
import Data.Vector.Unboxed.Deriving
import GHC.TypeNats
import qualified Data.Vector.Unboxed.Sized as S

data ChunkIndex = ChunkIndex {ChunkIndex -> Int
number :: {-# UNPACK #-} !Int , ChunkIndex -> Int
index :: {-# UNPACK #-} !Int} deriving (ChunkIndex -> ChunkIndex -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ChunkIndex -> ChunkIndex -> Bool
$c/= :: ChunkIndex -> ChunkIndex -> Bool
== :: ChunkIndex -> ChunkIndex -> Bool
$c== :: ChunkIndex -> ChunkIndex -> Bool
Eq , Eq ChunkIndex
ChunkIndex -> ChunkIndex -> Bool
ChunkIndex -> ChunkIndex -> Ordering
ChunkIndex -> ChunkIndex -> ChunkIndex
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ChunkIndex -> ChunkIndex -> ChunkIndex
$cmin :: ChunkIndex -> ChunkIndex -> ChunkIndex
max :: ChunkIndex -> ChunkIndex -> ChunkIndex
$cmax :: ChunkIndex -> ChunkIndex -> ChunkIndex
>= :: ChunkIndex -> ChunkIndex -> Bool
$c>= :: ChunkIndex -> ChunkIndex -> Bool
> :: ChunkIndex -> ChunkIndex -> Bool
$c> :: ChunkIndex -> ChunkIndex -> Bool
<= :: ChunkIndex -> ChunkIndex -> Bool
$c<= :: ChunkIndex -> ChunkIndex -> Bool
< :: ChunkIndex -> ChunkIndex -> Bool
$c< :: ChunkIndex -> ChunkIndex -> Bool
compare :: ChunkIndex -> ChunkIndex -> Ordering
$ccompare :: ChunkIndex -> ChunkIndex -> Ordering
Ord , Int -> ChunkIndex -> ShowS
[ChunkIndex] -> ShowS
ChunkIndex -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ChunkIndex] -> ShowS
$cshowList :: [ChunkIndex] -> ShowS
show :: ChunkIndex -> String
$cshow :: ChunkIndex -> String
showsPrec :: Int -> ChunkIndex -> ShowS
$cshowsPrec :: Int -> ChunkIndex -> ShowS
Show)

derivingUnbox "ChunkIndex"
    [t| ChunkIndex -> (Int , Int) |]
    [|\(ChunkIndex i j) -> (i,j)|]
    [|\(i,j) -> ChunkIndex i j|]

data ScoredMatchSized (n::Nat) = ScoredMatchSized { forall (n :: Nat). ScoredMatchSized n -> Down Int
score :: {-# UNPACK #-} !(Down Int), forall (n :: Nat). ScoredMatchSized n -> ChunkIndex
chunkIndex :: {-# UNPACK #-} !ChunkIndex
                                                  , forall (n :: Nat). ScoredMatchSized n -> Vector n Int
matchData :: {-# UNPACK #-} !(S.Vector n Int)} deriving (Int -> ScoredMatchSized n -> ShowS
forall (n :: Nat). Int -> ScoredMatchSized n -> ShowS
forall (n :: Nat). [ScoredMatchSized n] -> ShowS
forall (n :: Nat). ScoredMatchSized n -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ScoredMatchSized n] -> ShowS
$cshowList :: forall (n :: Nat). [ScoredMatchSized n] -> ShowS
show :: ScoredMatchSized n -> String
$cshow :: forall (n :: Nat). ScoredMatchSized n -> String
showsPrec :: Int -> ScoredMatchSized n -> ShowS
$cshowsPrec :: forall (n :: Nat). Int -> ScoredMatchSized n -> ShowS
Show)

derivingUnbox "ScoredMatchSized"
    [t| forall (n::Nat). KnownNat n => ScoredMatchSized n -> (Int , Int , Int , S.Vector n Int) |]
    [| \(ScoredMatchSized (Down s) (ChunkIndex i j) m) -> (s, i , j , m) |]
    [| \(s, i , j , m) -> ScoredMatchSized (Down s) (ChunkIndex i j) m |]

instance Eq (ScoredMatchSized n) where
  (ScoredMatchSized Down Int
s ChunkIndex
i Vector n Int
_) == :: ScoredMatchSized n -> ScoredMatchSized n -> Bool
== (ScoredMatchSized Down Int
t ChunkIndex
j Vector n Int
_) = Down Int
s forall a. Eq a => a -> a -> Bool
== Down Int
t Bool -> Bool -> Bool
&& ChunkIndex
i forall a. Eq a => a -> a -> Bool
== ChunkIndex
j

instance Ord (ScoredMatchSized n) where
  compare :: ScoredMatchSized n -> ScoredMatchSized n -> Ordering
compare (ScoredMatchSized Down Int
s ChunkIndex
i Vector n Int
_) (ScoredMatchSized Down Int
t ChunkIndex
j Vector n Int
_) = forall a. Ord a => a -> a -> Ordering
compare (Down Int
s,ChunkIndex
i) (Down Int
t,ChunkIndex
j)

emptyMatch :: Int -> Int -> ScoredMatchSized 0
emptyMatch :: Int -> Int -> ScoredMatchSized 0
emptyMatch Int
i Int
j = forall (n :: Nat).
Down Int -> ChunkIndex -> Vector n Int -> ScoredMatchSized n
ScoredMatchSized Down Int
0 (Int -> Int -> ChunkIndex
ChunkIndex Int
i Int
j) forall a. Unbox a => Vector 0 a
S.empty