{-# OPTIONS_GHC -Wall #-}
{-# OPTIONS_HADDOCK show-extensions #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  ToySolver.Converter.Base
-- Copyright   :  (c) Masahiro Sakai 2018
-- License     :  BSD-style
--
-- Maintainer  :  masahiro.sakai@gmail.com
-- Stability   :  experimental
-- Portability :  non-portable
--
-----------------------------------------------------------------------------
module ToySolver.Converter.Base
  ( Transformer (..)
  , ForwardTransformer (..)
  , BackwardTransformer (..)
  , ObjValueTransformer (..)
  , ObjValueForwardTransformer (..)
  , ObjValueBackwardTransformer (..)
  , ComposedTransformer (..)
  , IdentityTransformer (..)
  , ReversedTransformer (..)
  ) where


class (Eq a, Show a) => Transformer a where
  type Source a
  type Target a

class Transformer a => ForwardTransformer a where
  transformForward :: a -> Source a -> Target a

class Transformer a => BackwardTransformer a where
  transformBackward :: a -> Target a -> Source a


class ObjValueTransformer a where
  type SourceObjValue a
  type TargetObjValue a

class ObjValueTransformer a => ObjValueForwardTransformer a where
  transformObjValueForward :: a -> SourceObjValue a -> TargetObjValue a

class ObjValueTransformer a => ObjValueBackwardTransformer a where
  transformObjValueBackward :: a -> TargetObjValue a -> SourceObjValue a


data ComposedTransformer a b = ComposedTransformer a b
  deriving (ComposedTransformer a b -> ComposedTransformer a b -> Bool
(ComposedTransformer a b -> ComposedTransformer a b -> Bool)
-> (ComposedTransformer a b -> ComposedTransformer a b -> Bool)
-> Eq (ComposedTransformer a b)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall a b.
(Eq a, Eq b) =>
ComposedTransformer a b -> ComposedTransformer a b -> Bool
/= :: ComposedTransformer a b -> ComposedTransformer a b -> Bool
$c/= :: forall a b.
(Eq a, Eq b) =>
ComposedTransformer a b -> ComposedTransformer a b -> Bool
== :: ComposedTransformer a b -> ComposedTransformer a b -> Bool
$c== :: forall a b.
(Eq a, Eq b) =>
ComposedTransformer a b -> ComposedTransformer a b -> Bool
Eq, Int -> ComposedTransformer a b -> ShowS
[ComposedTransformer a b] -> ShowS
ComposedTransformer a b -> String
(Int -> ComposedTransformer a b -> ShowS)
-> (ComposedTransformer a b -> String)
-> ([ComposedTransformer a b] -> ShowS)
-> Show (ComposedTransformer a b)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall a b.
(Show a, Show b) =>
Int -> ComposedTransformer a b -> ShowS
forall a b. (Show a, Show b) => [ComposedTransformer a b] -> ShowS
forall a b. (Show a, Show b) => ComposedTransformer a b -> String
showList :: [ComposedTransformer a b] -> ShowS
$cshowList :: forall a b. (Show a, Show b) => [ComposedTransformer a b] -> ShowS
show :: ComposedTransformer a b -> String
$cshow :: forall a b. (Show a, Show b) => ComposedTransformer a b -> String
showsPrec :: Int -> ComposedTransformer a b -> ShowS
$cshowsPrec :: forall a b.
(Show a, Show b) =>
Int -> ComposedTransformer a b -> ShowS
Show, ReadPrec [ComposedTransformer a b]
ReadPrec (ComposedTransformer a b)
Int -> ReadS (ComposedTransformer a b)
ReadS [ComposedTransformer a b]
(Int -> ReadS (ComposedTransformer a b))
-> ReadS [ComposedTransformer a b]
-> ReadPrec (ComposedTransformer a b)
-> ReadPrec [ComposedTransformer a b]
-> Read (ComposedTransformer a b)
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
forall a b. (Read a, Read b) => ReadPrec [ComposedTransformer a b]
forall a b. (Read a, Read b) => ReadPrec (ComposedTransformer a b)
forall a b.
(Read a, Read b) =>
Int -> ReadS (ComposedTransformer a b)
forall a b. (Read a, Read b) => ReadS [ComposedTransformer a b]
readListPrec :: ReadPrec [ComposedTransformer a b]
$creadListPrec :: forall a b. (Read a, Read b) => ReadPrec [ComposedTransformer a b]
readPrec :: ReadPrec (ComposedTransformer a b)
$creadPrec :: forall a b. (Read a, Read b) => ReadPrec (ComposedTransformer a b)
readList :: ReadS [ComposedTransformer a b]
$creadList :: forall a b. (Read a, Read b) => ReadS [ComposedTransformer a b]
readsPrec :: Int -> ReadS (ComposedTransformer a b)
$creadsPrec :: forall a b.
(Read a, Read b) =>
Int -> ReadS (ComposedTransformer a b)
Read)

instance (Transformer a, Transformer b, Target a ~ Source b) => Transformer (ComposedTransformer a b) where
  type Source (ComposedTransformer a b) = Source a
  type Target (ComposedTransformer a b) = Target b

instance (ForwardTransformer a, ForwardTransformer b, Target a ~ Source b)
  => ForwardTransformer (ComposedTransformer a b) where
  transformForward :: ComposedTransformer a b
-> Source (ComposedTransformer a b)
-> Target (ComposedTransformer a b)
transformForward (ComposedTransformer a
a b
b) = b -> Source b -> Target b
forall a. ForwardTransformer a => a -> Source a -> Target a
transformForward b
b (Source b -> Target b)
-> (Source a -> Source b) -> Source a -> Target b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Source a -> Target a
forall a. ForwardTransformer a => a -> Source a -> Target a
transformForward a
a

instance (BackwardTransformer a, BackwardTransformer b, Target a ~ Source b)
  => BackwardTransformer (ComposedTransformer a b) where
  transformBackward :: ComposedTransformer a b
-> Target (ComposedTransformer a b)
-> Source (ComposedTransformer a b)
transformBackward (ComposedTransformer a
a b
b) = a -> Target a -> Source a
forall a. BackwardTransformer a => a -> Target a -> Source a
transformBackward a
a (Source b -> Source a)
-> (Target b -> Source b) -> Target b -> Source a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> Target b -> Source b
forall a. BackwardTransformer a => a -> Target a -> Source a
transformBackward b
b


instance (ObjValueTransformer a, ObjValueTransformer b, TargetObjValue a ~ SourceObjValue b)
  => ObjValueTransformer (ComposedTransformer a b) where
  type SourceObjValue (ComposedTransformer a b) = SourceObjValue a
  type TargetObjValue (ComposedTransformer a b) = TargetObjValue b

instance (ObjValueForwardTransformer a, ObjValueForwardTransformer b, TargetObjValue a ~ SourceObjValue b)
  => ObjValueForwardTransformer (ComposedTransformer a b) where
  transformObjValueForward :: ComposedTransformer a b
-> SourceObjValue (ComposedTransformer a b)
-> TargetObjValue (ComposedTransformer a b)
transformObjValueForward (ComposedTransformer a
a b
b) = b -> SourceObjValue b -> TargetObjValue b
forall a.
ObjValueForwardTransformer a =>
a -> SourceObjValue a -> TargetObjValue a
transformObjValueForward b
b (SourceObjValue b -> TargetObjValue b)
-> (SourceObjValue a -> SourceObjValue b)
-> SourceObjValue a
-> TargetObjValue b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> SourceObjValue a -> TargetObjValue a
forall a.
ObjValueForwardTransformer a =>
a -> SourceObjValue a -> TargetObjValue a
transformObjValueForward a
a

instance (ObjValueBackwardTransformer a, ObjValueBackwardTransformer b, TargetObjValue a ~ SourceObjValue b)
  => ObjValueBackwardTransformer (ComposedTransformer a b) where
  transformObjValueBackward :: ComposedTransformer a b
-> TargetObjValue (ComposedTransformer a b)
-> SourceObjValue (ComposedTransformer a b)
transformObjValueBackward (ComposedTransformer a
a b
b) = a -> TargetObjValue a -> SourceObjValue a
forall a.
ObjValueBackwardTransformer a =>
a -> TargetObjValue a -> SourceObjValue a
transformObjValueBackward a
a (SourceObjValue b -> SourceObjValue a)
-> (TargetObjValue b -> SourceObjValue b)
-> TargetObjValue b
-> SourceObjValue a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> TargetObjValue b -> SourceObjValue b
forall a.
ObjValueBackwardTransformer a =>
a -> TargetObjValue a -> SourceObjValue a
transformObjValueBackward b
b



data IdentityTransformer a = IdentityTransformer
  deriving (IdentityTransformer a -> IdentityTransformer a -> Bool
(IdentityTransformer a -> IdentityTransformer a -> Bool)
-> (IdentityTransformer a -> IdentityTransformer a -> Bool)
-> Eq (IdentityTransformer a)
forall a. IdentityTransformer a -> IdentityTransformer a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: IdentityTransformer a -> IdentityTransformer a -> Bool
$c/= :: forall a. IdentityTransformer a -> IdentityTransformer a -> Bool
== :: IdentityTransformer a -> IdentityTransformer a -> Bool
$c== :: forall a. IdentityTransformer a -> IdentityTransformer a -> Bool
Eq, Int -> IdentityTransformer a -> ShowS
[IdentityTransformer a] -> ShowS
IdentityTransformer a -> String
(Int -> IdentityTransformer a -> ShowS)
-> (IdentityTransformer a -> String)
-> ([IdentityTransformer a] -> ShowS)
-> Show (IdentityTransformer a)
forall a. Int -> IdentityTransformer a -> ShowS
forall a. [IdentityTransformer a] -> ShowS
forall a. IdentityTransformer a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [IdentityTransformer a] -> ShowS
$cshowList :: forall a. [IdentityTransformer a] -> ShowS
show :: IdentityTransformer a -> String
$cshow :: forall a. IdentityTransformer a -> String
showsPrec :: Int -> IdentityTransformer a -> ShowS
$cshowsPrec :: forall a. Int -> IdentityTransformer a -> ShowS
Show, ReadPrec [IdentityTransformer a]
ReadPrec (IdentityTransformer a)
Int -> ReadS (IdentityTransformer a)
ReadS [IdentityTransformer a]
(Int -> ReadS (IdentityTransformer a))
-> ReadS [IdentityTransformer a]
-> ReadPrec (IdentityTransformer a)
-> ReadPrec [IdentityTransformer a]
-> Read (IdentityTransformer a)
forall a. ReadPrec [IdentityTransformer a]
forall a. ReadPrec (IdentityTransformer a)
forall a. Int -> ReadS (IdentityTransformer a)
forall a. ReadS [IdentityTransformer a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [IdentityTransformer a]
$creadListPrec :: forall a. ReadPrec [IdentityTransformer a]
readPrec :: ReadPrec (IdentityTransformer a)
$creadPrec :: forall a. ReadPrec (IdentityTransformer a)
readList :: ReadS [IdentityTransformer a]
$creadList :: forall a. ReadS [IdentityTransformer a]
readsPrec :: Int -> ReadS (IdentityTransformer a)
$creadsPrec :: forall a. Int -> ReadS (IdentityTransformer a)
Read)

instance Transformer (IdentityTransformer a) where
  type Source (IdentityTransformer a) = a
  type Target (IdentityTransformer a) = a

instance ForwardTransformer (IdentityTransformer a) where
  transformForward :: IdentityTransformer a
-> Source (IdentityTransformer a) -> Target (IdentityTransformer a)
transformForward IdentityTransformer a
IdentityTransformer = Source (IdentityTransformer a) -> Target (IdentityTransformer a)
forall a. a -> a
id

instance BackwardTransformer (IdentityTransformer a) where
  transformBackward :: IdentityTransformer a
-> Target (IdentityTransformer a) -> Source (IdentityTransformer a)
transformBackward IdentityTransformer a
IdentityTransformer = Target (IdentityTransformer a) -> Source (IdentityTransformer a)
forall a. a -> a
id


data ReversedTransformer t = ReversedTransformer t
  deriving (ReversedTransformer t -> ReversedTransformer t -> Bool
(ReversedTransformer t -> ReversedTransformer t -> Bool)
-> (ReversedTransformer t -> ReversedTransformer t -> Bool)
-> Eq (ReversedTransformer t)
forall t.
Eq t =>
ReversedTransformer t -> ReversedTransformer t -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ReversedTransformer t -> ReversedTransformer t -> Bool
$c/= :: forall t.
Eq t =>
ReversedTransformer t -> ReversedTransformer t -> Bool
== :: ReversedTransformer t -> ReversedTransformer t -> Bool
$c== :: forall t.
Eq t =>
ReversedTransformer t -> ReversedTransformer t -> Bool
Eq, Int -> ReversedTransformer t -> ShowS
[ReversedTransformer t] -> ShowS
ReversedTransformer t -> String
(Int -> ReversedTransformer t -> ShowS)
-> (ReversedTransformer t -> String)
-> ([ReversedTransformer t] -> ShowS)
-> Show (ReversedTransformer t)
forall t. Show t => Int -> ReversedTransformer t -> ShowS
forall t. Show t => [ReversedTransformer t] -> ShowS
forall t. Show t => ReversedTransformer t -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ReversedTransformer t] -> ShowS
$cshowList :: forall t. Show t => [ReversedTransformer t] -> ShowS
show :: ReversedTransformer t -> String
$cshow :: forall t. Show t => ReversedTransformer t -> String
showsPrec :: Int -> ReversedTransformer t -> ShowS
$cshowsPrec :: forall t. Show t => Int -> ReversedTransformer t -> ShowS
Show, ReadPrec [ReversedTransformer t]
ReadPrec (ReversedTransformer t)
Int -> ReadS (ReversedTransformer t)
ReadS [ReversedTransformer t]
(Int -> ReadS (ReversedTransformer t))
-> ReadS [ReversedTransformer t]
-> ReadPrec (ReversedTransformer t)
-> ReadPrec [ReversedTransformer t]
-> Read (ReversedTransformer t)
forall t. Read t => ReadPrec [ReversedTransformer t]
forall t. Read t => ReadPrec (ReversedTransformer t)
forall t. Read t => Int -> ReadS (ReversedTransformer t)
forall t. Read t => ReadS [ReversedTransformer t]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ReversedTransformer t]
$creadListPrec :: forall t. Read t => ReadPrec [ReversedTransformer t]
readPrec :: ReadPrec (ReversedTransformer t)
$creadPrec :: forall t. Read t => ReadPrec (ReversedTransformer t)
readList :: ReadS [ReversedTransformer t]
$creadList :: forall t. Read t => ReadS [ReversedTransformer t]
readsPrec :: Int -> ReadS (ReversedTransformer t)
$creadsPrec :: forall t. Read t => Int -> ReadS (ReversedTransformer t)
Read)

instance Transformer t => Transformer (ReversedTransformer t) where
  type Source (ReversedTransformer t) = Target t
  type Target (ReversedTransformer t) = Source t

instance BackwardTransformer t => ForwardTransformer (ReversedTransformer t) where
  transformForward :: ReversedTransformer t
-> Source (ReversedTransformer t) -> Target (ReversedTransformer t)
transformForward (ReversedTransformer t
t) = t -> Target t -> Source t
forall a. BackwardTransformer a => a -> Target a -> Source a
transformBackward t
t

instance ForwardTransformer t => BackwardTransformer (ReversedTransformer t) where
  transformBackward :: ReversedTransformer t
-> Target (ReversedTransformer t) -> Source (ReversedTransformer t)
transformBackward (ReversedTransformer t
t) = t -> Source t -> Target t
forall a. ForwardTransformer a => a -> Source a -> Target a
transformForward t
t

instance ObjValueTransformer t => ObjValueTransformer (ReversedTransformer t) where
  type SourceObjValue (ReversedTransformer t) = TargetObjValue t
  type TargetObjValue (ReversedTransformer t) = SourceObjValue t

instance ObjValueBackwardTransformer t => ObjValueForwardTransformer (ReversedTransformer t) where
  transformObjValueForward :: ReversedTransformer t
-> SourceObjValue (ReversedTransformer t)
-> TargetObjValue (ReversedTransformer t)
transformObjValueForward (ReversedTransformer t
t) = t -> TargetObjValue t -> SourceObjValue t
forall a.
ObjValueBackwardTransformer a =>
a -> TargetObjValue a -> SourceObjValue a
transformObjValueBackward t
t

instance ObjValueForwardTransformer t => ObjValueBackwardTransformer (ReversedTransformer t) where
  transformObjValueBackward :: ReversedTransformer t
-> TargetObjValue (ReversedTransformer t)
-> SourceObjValue (ReversedTransformer t)
transformObjValueBackward (ReversedTransformer t
t) = t -> SourceObjValue t -> TargetObjValue t
forall a.
ObjValueForwardTransformer a =>
a -> SourceObjValue a -> TargetObjValue a
transformObjValueForward t
t