{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE BangPatterns #-}
module Data.PreNatMap(
PreNatMap(), PreEntry(..),
empty,
isFull,
fullMatch, match,
lookup, lookupWith, lookupShape,
refine, refineShape,
toEntries, fromEntries, make,
toNatMap, fromNatMap, toShapeMap, fromShapeMap,
) where
import Prelude hiding (lookup)
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import qualified Data.IntMap.Strict as IntMap
import Data.Foldable (Foldable(..))
import Data.FunctorShape
import qualified Data.Vector.Unboxed as UV
import qualified Data.Vector as V
import Control.Monad (guard)
import Data.Maybe (fromMaybe, mapMaybe)
import Data.Functor.Classes (showsUnaryWith)
import Data.NatMap (NatMap)
import qualified Data.NatMap as NM
import TraversableUtil (indices, zipMatch)
newtype PreNatMap f g = PreNatMap (Map (Shape f) (PosData g))
deriving instance (Eq (f Ignored), Eq (g Int)) => Eq (PreNatMap f g)
deriving instance (Ord (f Ignored), Ord (g Int)) => Ord (PreNatMap f g)
instance (Show (f Int), Show (g Int), Traversable f, Functor g) => Show (PreNatMap f g) where
showsPrec :: Int -> PreNatMap f g -> ShowS
showsPrec Int
p PreNatMap f g
pnm = (Int -> [PreEntry f g] -> ShowS)
-> String -> Int -> [PreEntry f g] -> ShowS
forall a. (Int -> a -> ShowS) -> String -> Int -> a -> ShowS
showsUnaryWith Int -> [PreEntry f g] -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec String
"make" Int
p (PreNatMap f g -> [PreEntry f g]
forall (f :: * -> *) (g :: * -> *).
(Traversable f, Functor g) =>
PreNatMap f g -> [PreEntry f g]
toEntries PreNatMap f g
pnm)
data PosData g = PosData
!(UV.Vector Int)
!(g Int)
deriving instance (Eq (g Int)) => Eq (PosData g)
deriving instance (Ord (g Int)) => Ord (PosData g)
data PreEntry f g = PreEntry (f Int) (g Int)
deriving instance (Show (f Int), Show (g Int)) => Show (PreEntry f g)
deriving instance (Eq (f Int), Eq (g Int)) => Eq (PreEntry f g)
deriving instance (Ord (f Int), Ord (g Int)) => Ord (PreEntry f g)
empty :: PreNatMap f g
empty :: forall (f :: * -> *) (g :: * -> *). PreNatMap f g
empty = Map (Shape f) (PosData g) -> PreNatMap f g
forall (f :: * -> *) (g :: * -> *).
Map (Shape f) (PosData g) -> PreNatMap f g
PreNatMap Map (Shape f) (PosData g)
forall k a. Map k a
Map.empty
toEntries :: (Traversable f, Functor g) => PreNatMap f g -> [PreEntry f g]
toEntries :: forall (f :: * -> *) (g :: * -> *).
(Traversable f, Functor g) =>
PreNatMap f g -> [PreEntry f g]
toEntries (PreNatMap Map (Shape f) (PosData g)
pnm) = (Shape f, PosData g) -> PreEntry f g
forall {f :: * -> *} {g :: * -> *}.
Traversable f =>
(Shape f, PosData g) -> PreEntry f g
preEntry ((Shape f, PosData g) -> PreEntry f g)
-> [(Shape f, PosData g)] -> [PreEntry f g]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map (Shape f) (PosData g) -> [(Shape f, PosData g)]
forall k a. Map k a -> [(k, a)]
Map.toList Map (Shape f) (PosData g)
pnm
where
preEntry :: (Shape f, PosData g) -> PreEntry f g
preEntry (Shape f a
f, PosData Vector Int
lhs g Int
rhs) = f Int -> g Int -> PreEntry f g
forall (f :: * -> *) (g :: * -> *). f Int -> g Int -> PreEntry f g
PreEntry f Int
fn g Int
rhs
where
fi :: f Int
fi = f a -> f Int
forall (f :: * -> *) x. Traversable f => f x -> f Int
indices f a
f
fn :: f Int
fn = (Vector Int
lhs Vector Int -> Int -> Int
forall a. Unbox a => Vector a -> Int -> a
UV.!) (Int -> Int) -> f Int -> f Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f Int
fi
fromEntries :: (Ord (f Ignored), Eq (g Ignored), Foldable f, Traversable g)
=> [PreEntry f g] -> Maybe (PreNatMap f g)
fromEntries :: forall (f :: * -> *) (g :: * -> *).
(Ord (f Ignored), Eq (g Ignored), Foldable f, Traversable g) =>
[PreEntry f g] -> Maybe (PreNatMap f g)
fromEntries = (Maybe (PreNatMap f g) -> PreEntry f g -> Maybe (PreNatMap f g))
-> Maybe (PreNatMap f g) -> [PreEntry f g] -> Maybe (PreNatMap f g)
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\Maybe (PreNatMap f g)
mm (PreEntry f Int
fn g Int
gn) -> Maybe (PreNatMap f g)
mm Maybe (PreNatMap f g)
-> (PreNatMap f g -> Maybe (PreNatMap f g))
-> Maybe (PreNatMap f g)
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ !PreNatMap f g
m -> f Int -> g Int -> PreNatMap f g -> Maybe (PreNatMap f g)
forall a (f :: * -> *) (g :: * -> *).
(Ord a, Ord (f Ignored), Eq (g Ignored), Foldable f,
Traversable g) =>
f a -> g a -> PreNatMap f g -> Maybe (PreNatMap f g)
refine f Int
fn g Int
gn PreNatMap f g
m) (PreNatMap f g -> Maybe (PreNatMap f g)
forall a. a -> Maybe a
Just PreNatMap f g
forall (f :: * -> *) (g :: * -> *). PreNatMap f g
empty)
make :: (Ord (f Ignored), Eq (g Ignored), Foldable f, Traversable g)
=> [PreEntry f g] -> PreNatMap f g
make :: forall (f :: * -> *) (g :: * -> *).
(Ord (f Ignored), Eq (g Ignored), Foldable f, Traversable g) =>
[PreEntry f g] -> PreNatMap f g
make = PreNatMap f g -> Maybe (PreNatMap f g) -> PreNatMap f g
forall a. a -> Maybe a -> a
fromMaybe (String -> PreNatMap f g
forall a. HasCallStack => String -> a
error String
"make: inconsistent entries") (Maybe (PreNatMap f g) -> PreNatMap f g)
-> ([PreEntry f g] -> Maybe (PreNatMap f g))
-> [PreEntry f g]
-> PreNatMap f g
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [PreEntry f g] -> Maybe (PreNatMap f g)
forall (f :: * -> *) (g :: * -> *).
(Ord (f Ignored), Eq (g Ignored), Foldable f, Traversable g) =>
[PreEntry f g] -> Maybe (PreNatMap f g)
fromEntries
toNatMap :: (Ord (f Ignored), Traversable f, Functor g) => PreNatMap f g -> NatMap f g
toNatMap :: forall (f :: * -> *) (g :: * -> *).
(Ord (f Ignored), Traversable f, Functor g) =>
PreNatMap f g -> NatMap f g
toNatMap (PreNatMap Map (Shape f) (PosData g)
pnm) = [Entry f g] -> NatMap f g
forall (f :: * -> *) (g :: * -> *).
WeakOrd f =>
[Entry f g] -> NatMap f g
NM.fromEntries ([Entry f g] -> NatMap f g) -> [Entry f g] -> NatMap f g
forall a b. (a -> b) -> a -> b
$ ((Shape f, PosData g) -> Maybe (Entry f g))
-> [(Shape f, PosData g)] -> [Entry f g]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (Shape f, PosData g) -> Maybe (Entry f g)
forall {f :: * -> *} {g :: * -> *}.
(Traversable f, Functor g) =>
(Shape f, PosData g) -> Maybe (Entry f g)
fullToEntry ([(Shape f, PosData g)] -> [Entry f g])
-> [(Shape f, PosData g)] -> [Entry f g]
forall a b. (a -> b) -> a -> b
$ Map (Shape f) (PosData g) -> [(Shape f, PosData g)]
forall k a. Map k a -> [(k, a)]
Map.toList Map (Shape f) (PosData g)
pnm
where
fullToEntry :: (Shape f, PosData g) -> Maybe (Entry f g)
fullToEntry (Shape f a
f, pd :: PosData g
pd@(PosData Vector Int
_ g Int
rhs))
| PosData g -> Bool
forall (g :: * -> *). PosData g -> Bool
isCompleteLHS PosData g
pd = Entry f g -> Maybe (Entry f g)
forall a. a -> Maybe a
Just (Entry f g -> Maybe (Entry f g)) -> Entry f g -> Maybe (Entry f g)
forall a b. (a -> b) -> a -> b
$ f Int -> g Int -> Entry f g
forall (f :: * -> *) (g :: * -> *) k.
(Traversable f, Functor g, Ord k) =>
f k -> g k -> Entry f g
NM.unsafeMakeEntry (f a -> f Int
forall (f :: * -> *) x. Traversable f => f x -> f Int
indices f a
f) g Int
rhs
| Bool
otherwise = Maybe (Entry f g)
forall a. Maybe a
Nothing
fromNatMap :: (Traversable f, Traversable g) => NatMap f g -> PreNatMap f g
fromNatMap :: forall (f :: * -> *) (g :: * -> *).
(Traversable f, Traversable g) =>
NatMap f g -> PreNatMap f g
fromNatMap NatMap f g
nm = Map (Shape f) (PosData g) -> PreNatMap f g
forall (f :: * -> *) (g :: * -> *).
Map (Shape f) (PosData g) -> PreNatMap f g
PreNatMap (Map (Shape f) (PosData g) -> PreNatMap f g)
-> Map (Shape f) (PosData g) -> PreNatMap f g
forall a b. (a -> b) -> a -> b
$ [(Shape f, PosData g)] -> Map (Shape f) (PosData g)
forall k a. [(k, a)] -> Map k a
Map.fromDistinctAscList ([(Shape f, PosData g)] -> Map (Shape f) (PosData g))
-> [(Shape f, PosData g)] -> Map (Shape f) (PosData g)
forall a b. (a -> b) -> a -> b
$
Entry f g -> (Shape f, PosData g)
forall {g :: * -> *} {f :: * -> *}.
(Traversable g, Foldable f) =>
Entry f g -> (Shape f, PosData g)
entryToPosData (Entry f g -> (Shape f, PosData g))
-> [Entry f g] -> [(Shape f, PosData g)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NatMap f g -> [Entry f g]
forall (f :: * -> *) (g :: * -> *). NatMap f g -> [Entry f g]
NM.toEntries NatMap f g
nm
where
entryToPosData :: Entry f g -> (Shape f, PosData g)
entryToPosData Entry f g
e = (Shape f
f, PosData g
pd)
where
(Shape f
f, g Var
gx) = Entry f g -> (Shape f, g Var)
forall (f :: * -> *) (g :: * -> *). Entry f g -> (Shape f, g Var)
NM.getKeyValue Entry f g
e
vars :: [Var]
vars = Int -> [Var]
NM.makeVars (Shape f -> Int
forall (f :: * -> *). Foldable f => Shape f -> Int
lengthShape Shape f
f)
unreachable :: a
unreachable = String -> a
forall a. HasCallStack => String -> a
error String
"this makePosData can't fail"
pd :: PosData g
pd = PosData g -> Maybe (PosData g) -> PosData g
forall a. a -> Maybe a -> a
fromMaybe PosData g
forall {a}. a
unreachable (Maybe (PosData g) -> PosData g) -> Maybe (PosData g) -> PosData g
forall a b. (a -> b) -> a -> b
$ [Var] -> g Var -> Maybe (PosData g)
forall a (g :: * -> *).
(Ord a, Traversable g) =>
[a] -> g a -> Maybe (PosData g)
makePosData [Var]
vars g Var
gx
toShapeMap :: PreNatMap f g -> Map (Shape f) (Shape g)
toShapeMap :: forall (f :: * -> *) (g :: * -> *).
PreNatMap f g -> Map (Shape f) (Shape g)
toShapeMap (PreNatMap Map (Shape f) (PosData g)
pnm) = (PosData g -> Shape g)
-> Map (Shape f) (PosData g) -> Map (Shape f) (Shape g)
forall a b k. (a -> b) -> Map k a -> Map k b
Map.map (\ (PosData Vector Int
_ g Int
gi) -> g Int -> Shape g
forall (f :: * -> *) a. f a -> Shape f
Shape g Int
gi) Map (Shape f) (PosData g)
pnm
fromShapeMap :: (Foldable f, Traversable g) => Map (Shape f) (Shape g) -> Maybe (PreNatMap f g)
fromShapeMap :: forall (f :: * -> *) (g :: * -> *).
(Foldable f, Traversable g) =>
Map (Shape f) (Shape g) -> Maybe (PreNatMap f g)
fromShapeMap Map (Shape f) (Shape g)
m = Map (Shape f) (PosData g) -> PreNatMap f g
forall (f :: * -> *) (g :: * -> *).
Map (Shape f) (PosData g) -> PreNatMap f g
PreNatMap (Map (Shape f) (PosData g) -> PreNatMap f g)
-> Maybe (Map (Shape f) (PosData g)) -> Maybe (PreNatMap f g)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map (Shape f) (Maybe (PosData g))
-> Maybe (Map (Shape f) (PosData g))
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
forall (f :: * -> *) a.
Applicative f =>
Map (Shape f) (f a) -> f (Map (Shape f) a)
sequenceA ((Shape f -> Shape g -> Maybe (PosData g))
-> Map (Shape f) (Shape g) -> Map (Shape f) (Maybe (PosData g))
forall k a b. (k -> a -> b) -> Map k a -> Map k b
Map.mapWithKey Shape f -> Shape g -> Maybe (PosData g)
forall (f :: * -> *) (g :: * -> *).
(Foldable f, Traversable g) =>
Shape f -> Shape g -> Maybe (PosData g)
makeShapePosData Map (Shape f) (Shape g)
m)
match :: (Eq a, Ord (f Ignored), Foldable f, Functor g) => f a -> PreNatMap f g -> Maybe (g a)
match :: forall a (f :: * -> *) (g :: * -> *).
(Eq a, Ord (f Ignored), Foldable f, Functor g) =>
f a -> PreNatMap f g -> Maybe (g a)
match f a
fa (PreNatMap Map (Shape f) (PosData g)
pnm) = do
pd@(PosData lhs rhs) <- Shape f -> Map (Shape f) (PosData g) -> Maybe (PosData g)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (f a -> Shape f
forall (f :: * -> *) a. f a -> Shape f
Shape f a
fa) Map (Shape f) (PosData g)
pnm
if isCompleteLHS pd
then pure $ makeRHS (toList fa) pd
else do
funLhs <- functionalRelI (zip (UV.toList lhs) (toList fa))
let ga = (IntMap a
funLhs IntMap a -> Int -> a
forall a. IntMap a -> Int -> a
IntMap.!) (Int -> a) -> g Int -> g a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> g Int
rhs
pure ga
fullMatch :: (Ord (f Ignored), Foldable f, Functor g) => f a -> PreNatMap f g -> Maybe (g a)
fullMatch :: forall (f :: * -> *) (g :: * -> *) a.
(Ord (f Ignored), Foldable f, Functor g) =>
f a -> PreNatMap f g -> Maybe (g a)
fullMatch f a
fa (PreNatMap Map (Shape f) (PosData g)
pnm) = do
pd <- Shape f -> Map (Shape f) (PosData g) -> Maybe (PosData g)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (f a -> Shape f
forall (f :: * -> *) a. f a -> Shape f
Shape f a
fa) Map (Shape f) (PosData g)
pnm
if isCompleteLHS pd
then pure $ makeRHS (toList fa) pd
else Nothing
isFull :: (Ord (f Ignored), Foldable f, Functor g) => Shape f -> PreNatMap f g -> Bool
isFull :: forall (f :: * -> *) (g :: * -> *).
(Ord (f Ignored), Foldable f, Functor g) =>
Shape f -> PreNatMap f g -> Bool
isFull Shape f
f (PreNatMap Map (Shape f) (PosData g)
pnm) = Bool -> (PosData g -> Bool) -> Maybe (PosData g) -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
False PosData g -> Bool
forall (g :: * -> *). PosData g -> Bool
isCompleteLHS (Maybe (PosData g) -> Bool) -> Maybe (PosData g) -> Bool
forall a b. (a -> b) -> a -> b
$ Shape f -> Map (Shape f) (PosData g) -> Maybe (PosData g)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Shape f
f Map (Shape f) (PosData g)
pnm
lookup :: (Semigroup a, Ord (f Ignored), Foldable f, Functor g) => f a -> PreNatMap f g -> Maybe (g a)
lookup :: forall a (f :: * -> *) (g :: * -> *).
(Semigroup a, Ord (f Ignored), Foldable f, Functor g) =>
f a -> PreNatMap f g -> Maybe (g a)
lookup = (a -> a) -> f a -> PreNatMap f g -> Maybe (g a)
forall b (f :: * -> *) (g :: * -> *) a.
(Semigroup b, Ord (f Ignored), Foldable f, Functor g) =>
(a -> b) -> f a -> PreNatMap f g -> Maybe (g b)
lookupWith a -> a
forall a. a -> a
id
lookupWith :: (Semigroup b, Ord (f Ignored), Foldable f, Functor g) => (a -> b) -> f a -> PreNatMap f g -> Maybe (g b)
lookupWith :: forall b (f :: * -> *) (g :: * -> *) a.
(Semigroup b, Ord (f Ignored), Foldable f, Functor g) =>
(a -> b) -> f a -> PreNatMap f g -> Maybe (g b)
lookupWith a -> b
h f a
fa (PreNatMap Map (Shape f) (PosData g)
pnm) = do
pd@(PosData lhs rhs) <- Shape f -> Map (Shape f) (PosData g) -> Maybe (PosData g)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (f a -> Shape f
forall (f :: * -> *) a. f a -> Shape f
Shape f a
fa) Map (Shape f) (PosData g)
pnm
let bs = a -> b
h (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f a -> [a]
forall a. f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList f a
fa
funLhs = (b -> b -> b) -> [(Int, b)] -> IntMap b
forall a. (a -> a -> a) -> [(Int, a)] -> IntMap a
IntMap.fromListWith b -> b -> b
forall a. Semigroup a => a -> a -> a
(<>) ([Int] -> [b] -> [(Int, b)]
forall a b. [a] -> [b] -> [(a, b)]
zip (Vector Int -> [Int]
forall a. Unbox a => Vector a -> [a]
UV.toList Vector Int
lhs) [b]
bs)
gb | PosData g -> Bool
forall (g :: * -> *). PosData g -> Bool
isCompleteLHS PosData g
pd = [b] -> PosData g -> g b
forall (g :: * -> *) a. Functor g => [a] -> PosData g -> g a
makeRHS [b]
bs PosData g
pd
| Bool
otherwise = (IntMap b
funLhs IntMap b -> Int -> b
forall a. IntMap a -> Int -> a
IntMap.!) (Int -> b) -> g Int -> g b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> g Int
rhs
pure gb
lookupShape :: Ord (f Ignored) => Shape f -> PreNatMap f g -> Maybe (Shape g)
lookupShape :: forall (f :: * -> *) (g :: * -> *).
Ord (f Ignored) =>
Shape f -> PreNatMap f g -> Maybe (Shape g)
lookupShape Shape f
f (PreNatMap Map (Shape f) (PosData g)
pnm) = case Shape f -> Map (Shape f) (PosData g) -> Maybe (PosData g)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Shape f
f Map (Shape f) (PosData g)
pnm of
Maybe (PosData g)
Nothing -> Maybe (Shape g)
forall a. Maybe a
Nothing
Just (PosData Vector Int
_ g Int
rhs) -> Shape g -> Maybe (Shape g)
forall a. a -> Maybe a
Just (g Int -> Shape g
forall (f :: * -> *) a. f a -> Shape f
Shape g Int
rhs)
refine :: (Ord a, Ord (f Ignored), Eq (g Ignored), Foldable f, Traversable g) => f a -> g a -> PreNatMap f g -> Maybe (PreNatMap f g)
refine :: forall a (f :: * -> *) (g :: * -> *).
(Ord a, Ord (f Ignored), Eq (g Ignored), Foldable f,
Traversable g) =>
f a -> g a -> PreNatMap f g -> Maybe (PreNatMap f g)
refine f a
fa g a
ga (PreNatMap Map (Shape f) (PosData g)
pnm) = case Shape f -> Map (Shape f) (PosData g) -> Maybe (PosData g)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (f a -> Shape f
forall (f :: * -> *) a. f a -> Shape f
Shape f a
fa) Map (Shape f) (PosData g)
pnm of
Maybe (PosData g)
Nothing -> do
pd <- [a] -> g a -> Maybe (PosData g)
forall a (g :: * -> *).
(Ord a, Traversable g) =>
[a] -> g a -> Maybe (PosData g)
makePosData (f a -> [a]
forall a. f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList f a
fa) g a
ga
pure $ PreNatMap $ Map.insert (Shape fa) pd pnm
Just PosData g
pd -> do
pd' <- PosData g -> [a] -> g a -> Maybe (PosData g)
forall a (g :: * -> *).
(Ord a, Eq (g Ignored), Traversable g) =>
PosData g -> [a] -> g a -> Maybe (PosData g)
refinePosData PosData g
pd (f a -> [a]
forall a. f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList f a
fa) g a
ga
pure $ PreNatMap $ Map.insert (Shape fa) pd' pnm
refineShape :: (Ord (f Ignored), Eq (g Ignored), Foldable f, Traversable g)
=> Shape f -> Shape g -> PreNatMap f g -> Maybe (PreNatMap f g)
refineShape :: forall (f :: * -> *) (g :: * -> *).
(Ord (f Ignored), Eq (g Ignored), Foldable f, Traversable g) =>
Shape f -> Shape g -> PreNatMap f g -> Maybe (PreNatMap f g)
refineShape Shape f
f Shape g
g (PreNatMap Map (Shape f) (PosData g)
pnm) = case Shape f -> Map (Shape f) (PosData g) -> Maybe (PosData g)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Shape f
f Map (Shape f) (PosData g)
pnm of
Maybe (PosData g)
Nothing -> do
pd <- Shape f -> Shape g -> Maybe (PosData g)
forall (f :: * -> *) (g :: * -> *).
(Foldable f, Traversable g) =>
Shape f -> Shape g -> Maybe (PosData g)
makeShapePosData Shape f
f Shape g
g
pure $ PreNatMap $ Map.insert f pd pnm
Just (PosData Vector Int
_ g Int
gx) -> Map (Shape f) (PosData g) -> PreNatMap f g
forall (f :: * -> *) (g :: * -> *).
Map (Shape f) (PosData g) -> PreNatMap f g
PreNatMap Map (Shape f) (PosData g)
pnm PreNatMap f g -> Maybe () -> Maybe (PreNatMap f g)
forall a b. a -> Maybe b -> Maybe a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Shape g
g Shape g -> Shape g -> Bool
forall a. Eq a => a -> a -> Bool
== g Int -> Shape g
forall (f :: * -> *) a. f a -> Shape f
Shape g Int
gx)
isCompleteLHS :: PosData g -> Bool
isCompleteLHS :: forall (g :: * -> *). PosData g -> Bool
isCompleteLHS (PosData Vector Int
lhs g Int
_) = Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 Bool -> Bool -> Bool
|| Vector Int
lhs Vector Int -> Int -> Int
forall a. Unbox a => Vector a -> Int -> a
UV.! (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
where
n :: Int
n = Vector Int -> Int
forall a. Unbox a => Vector a -> Int
UV.length Vector Int
lhs
makeRHS :: Functor g => [a] -> PosData g -> g a
makeRHS :: forall (g :: * -> *) a. Functor g => [a] -> PosData g -> g a
makeRHS [a]
as (PosData Vector Int
_ g Int
gi) =
let aVec :: Vector a
aVec = [a] -> Vector a
forall a. [a] -> Vector a
V.fromList [a]
as
in (Vector a
aVec Vector a -> Int -> a
forall a. Vector a -> Int -> a
V.!) (Int -> a) -> g Int -> g a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> g Int
gi
functionalRelI :: (Eq a) => [(Int, a)] -> Maybe (IntMap.IntMap a)
functionalRelI :: forall a. Eq a => [(Int, a)] -> Maybe (IntMap a)
functionalRelI = IntMap a -> [(Int, a)] -> Maybe (IntMap a)
forall {a}. Eq a => IntMap a -> [(Int, a)] -> Maybe (IntMap a)
loop IntMap a
forall a. IntMap a
IntMap.empty
where
loop :: IntMap a -> [(Int, a)] -> Maybe (IntMap a)
loop IntMap a
m [] = IntMap a -> Maybe (IntMap a)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure IntMap a
m
loop IntMap a
m ((Int
k,a
v) : [(Int, a)]
rest) = case Int -> IntMap a -> Maybe a
forall a. Int -> IntMap a -> Maybe a
IntMap.lookup Int
k IntMap a
m of
Maybe a
Nothing -> IntMap a -> [(Int, a)] -> Maybe (IntMap a)
loop (Int -> a -> IntMap a -> IntMap a
forall a. Int -> a -> IntMap a -> IntMap a
IntMap.insert Int
k a
v IntMap a
m) [(Int, a)]
rest
Just a
v'
| a
v a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
v' -> IntMap a -> [(Int, a)] -> Maybe (IntMap a)
loop IntMap a
m [(Int, a)]
rest
| Bool
otherwise -> Maybe (IntMap a)
forall a. Maybe a
Nothing
makePosData :: (Ord a, Traversable g) => [a] -> g a -> Maybe (PosData g)
makePosData :: forall a (g :: * -> *).
(Ord a, Traversable g) =>
[a] -> g a -> Maybe (PosData g)
makePosData [a]
as g a
ga = do
(lhs, rhs) <- [a] -> g a -> Maybe (Vector Int, g Int)
forall a (g :: * -> *).
(Ord a, Traversable g) =>
[a] -> g a -> Maybe (Vector Int, g Int)
toRel [a]
as g a
ga
pure $ PosData lhs rhs
makeShapePosData :: (Foldable f, Traversable g)
=> Shape f -> Shape g -> Maybe (PosData g)
makeShapePosData :: forall (f :: * -> *) (g :: * -> *).
(Foldable f, Traversable g) =>
Shape f -> Shape g -> Maybe (PosData g)
makeShapePosData (Shape f a
f) (Shape g a
g)
| f a -> Bool
forall a. f a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null f a
f Bool -> Bool -> Bool
&& Bool -> Bool
not (g a -> Bool
forall a. g a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null g a
g) = Maybe (PosData g)
forall a. Maybe a
Nothing
| Bool
otherwise = PosData g -> Maybe (PosData g)
forall a. a -> Maybe a
Just (PosData g -> Maybe (PosData g)) -> PosData g -> Maybe (PosData g)
forall a b. (a -> b) -> a -> b
$ Vector Int -> g Int -> PosData g
forall (g :: * -> *). Vector Int -> g Int -> PosData g
PosData Vector Int
lhs g Int
rhs
where
lhs :: Vector Int
lhs = Int -> Int -> Vector Int
forall a. Unbox a => Int -> a -> Vector a
UV.replicate (f a -> Int
forall a. f a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length f a
f) Int
0
rhs :: g Int
rhs = Int
0 Int -> g a -> g Int
forall a b. a -> g b -> g a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ g a
g
refinePosData :: (Ord a, Eq (g Ignored), Traversable g) => PosData g -> [a] -> g a -> Maybe (PosData g)
refinePosData :: forall a (g :: * -> *).
(Ord a, Eq (g Ignored), Traversable g) =>
PosData g -> [a] -> g a -> Maybe (PosData g)
refinePosData (PosData Vector Int
lhs g Int
rhs) [a]
as g a
ga = do
ga' <- g Int -> g a -> Maybe (g (Int, a))
forall (t :: * -> *) a b.
(Eq (t Ignored), Traversable t) =>
t a -> t b -> Maybe (t (a, b))
zipMatch g Int
rhs g a
ga
(lhs', rhs') <- toRel (zip (UV.toList lhs) as) ga'
guard $ UV.length lhs == UV.length lhs'
pure $ PosData lhs' rhs'
toRel :: (Ord a, Traversable g) => [a] -> g a -> Maybe (UV.Vector Int, g Int)
toRel :: forall a (g :: * -> *).
(Ord a, Traversable g) =>
[a] -> g a -> Maybe (Vector Int, g Int)
toRel [a]
as g a
ga = (,) Vector Int
lhs (g Int -> (Vector Int, g Int))
-> Maybe (g Int) -> Maybe (Vector Int, g Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (g Int)
rhs
where
([Int]
lhsList, Map a Int
revmap) = [a] -> ([Int], Map a Int)
forall a. Ord a => [a] -> ([Int], Map a Int)
reindex [a]
as
lhs :: Vector Int
lhs = [Int] -> Vector Int
forall a. Unbox a => [a] -> Vector a
UV.fromList [Int]
lhsList
rhs :: Maybe (g Int)
rhs = (a -> Maybe Int) -> g a -> Maybe (g Int)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> g a -> f (g b)
traverse (a -> Map a Int -> Maybe Int
forall k a. Ord k => k -> Map k a -> Maybe a
`Map.lookup` Map a Int
revmap) g a
ga
reindex :: (Ord a) => [a] -> ([Int], Map a Int)
reindex :: forall a. Ord a => [a] -> ([Int], Map a Int)
reindex = [Int] -> Map a Int -> [a] -> ([Int], Map a Int)
forall {k}.
Ord k =>
[Int] -> Map k Int -> [k] -> ([Int], Map k Int)
loop [] Map a Int
forall k a. Map k a
Map.empty
where
loop :: [Int] -> Map k Int -> [k] -> ([Int], Map k Int)
loop [Int]
ixAccum Map k Int
rev [] = ([Int] -> [Int]
forall a. [a] -> [a]
reverse [Int]
ixAccum, Map k Int
rev)
loop [Int]
ixAccum Map k Int
rev (k
a : [k]
rest) = case k -> Map k Int -> Maybe Int
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup k
a Map k Int
rev of
Maybe Int
Nothing ->
let n :: Int
n = Map k Int -> Int
forall k a. Map k a -> Int
Map.size Map k Int
rev
rev' :: Map k Int
rev' = k -> Int -> Map k Int -> Map k Int
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert k
a Int
n Map k Int
rev
in [Int] -> Map k Int -> [k] -> ([Int], Map k Int)
loop (Int
n Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: [Int]
ixAccum) Map k Int
rev' [k]
rest
Just Int
n -> [Int] -> Map k Int -> [k] -> ([Int], Map k Int)
loop (Int
n Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: [Int]
ixAccum) Map k Int
rev [k]
rest