{-|
Module      : Test.Multivariant.Types.Solution
Description : Interpreter for solution
Copyright   : (c) Anton Marchenko, Mansur Ziatdinov, 2016-2017
License     : BSD-3
Maintainer  : gltronred@gmail.com
Stability   : provisional
Portability : POSIX

This module provides interpreter for solution.
-}

{-# LANGUAGE TypeOperators #-}

module Test.Multivariant.Types.Solution where

import Test.Multivariant.Classes

import Control.Arrow
import qualified Control.Invertible.BiArrow as BA
import Data.Invertible.Bijection
import qualified Data.Invertible.Function as Inv

-- | Type for interpreter
newtype Solution a b = Solution { solutions :: [a <-> b] }

-- | Extract a list of solutions (functions that map input to output)
getSolutions = map biTo . solutions

instance Program Solution where
  step f = Solution [f]
  a ~> b = Solution [sb Inv.. sa | sa <- solutions a, sb <- solutions b]
  a <***> b = Solution [sa *** sb | sa <- solutions a, sb <- solutions b]
  a <+++> b = Solution $ solutions a ++ solutions b

instance WithInvert Solution where
  invert (Solution fs) = Solution $ map BA.invert fs

instance WithCornerCases Solution where
  withCornerCases p _ = p

instance WithDescription Solution where
  withDescription p _ = p