{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE NegativeLiterals #-}
{-# OPTIONS_GHC -Wall -Werror #-}
module Documentation.SBV.Examples.Puzzles.AOC_2021_24 where
import Prelude hiding (read, mod, div)
import Data.Maybe
import qualified Data.Map.Strict as M
import qualified Control.Monad.State.Lazy as ST
import Data.SBV
type Register = String
type Value = SInt64
data Data = Reg {Data -> Register
register :: Register}
| Imm Int64
instance Num Data where
fromInteger :: Integer -> Data
fromInteger = Int64 -> Data
Imm forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral
+ :: Data -> Data -> Data
(+) = forall a. HasCallStack => Register -> a
error Register
"+ : unimplemented"
* :: Data -> Data -> Data
(*) = forall a. HasCallStack => Register -> a
error Register
"* : unimplemented"
negate :: Data -> Data
negate (Imm Int64
i) = Int64 -> Data
Imm (-Int64
i)
negate Reg{} = forall a. HasCallStack => Register -> a
error Register
"negate: unimplemented"
abs :: Data -> Data
abs = forall a. HasCallStack => Register -> a
error Register
"abs : unimplemented"
signum :: Data -> Data
signum = forall a. HasCallStack => Register -> a
error Register
"signum: unimplemented"
w :: Data
w :: Data
w = Register -> Data
Reg Register
"w"
x :: Data
x :: Data
x = Register -> Data
Reg Register
"x"
y :: Data
y :: Data
y = Register -> Data
Reg Register
"y"
z :: Data
z :: Data
z = Register -> Data
Reg Register
"z"
data State = State { State -> Map Register Value
env :: M.Map Register Value
, State -> [Value]
inputs :: [Value]
}
type ALU = ST.StateT State Symbolic
read :: Data -> ALU Value
read :: Data -> ALU Value
read (Reg Register
r) = forall s (m :: * -> *). MonadState s m => m s
ST.get forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \State
st -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. HasCallStack => Maybe a -> a
fromJust (Register
r forall k a. Ord k => k -> Map k a -> Maybe a
`M.lookup` State -> Map Register Value
env State
st)
read (Imm Int64
i) = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. SymVal a => a -> SBV a
literal Int64
i
write :: Data -> Value -> ALU ()
write :: Data -> Value -> ALU ()
write Data
d Value
v = forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
ST.modify' forall a b. (a -> b) -> a -> b
$ \State
st -> State
st{env :: Map Register Value
env = forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert (Data -> Register
register Data
d) Value
v (State -> Map Register Value
env State
st)}
inp :: Data -> ALU ()
inp :: Data -> ALU ()
inp Data
a = do Value
v <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
ST.lift forall a. SymVal a => Symbolic (SBV a)
free_
Data -> Value -> ALU ()
write Data
a Value
v
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
ST.modify' forall a b. (a -> b) -> a -> b
$ \State
st -> State
st{inputs :: [Value]
inputs = Value
v forall a. a -> [a] -> [a]
: State -> [Value]
inputs State
st}
add :: Data -> Data -> ALU ()
add :: Data -> Data -> ALU ()
add Data
a Data
b = Data -> Value -> ALU ()
write Data
a forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. Num a => a -> a -> a
(+) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Data -> ALU Value
read Data
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Data -> ALU Value
read Data
b
mul :: Data -> Data -> ALU ()
mul :: Data -> Data -> ALU ()
mul Data
a Data
b = Data -> Value -> ALU ()
write Data
a forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. Num a => a -> a -> a
(*) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Data -> ALU Value
read Data
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Data -> ALU Value
read Data
b
div :: Data -> Data -> ALU ()
div :: Data -> Data -> ALU ()
div Data
a Data
b = Data -> Value -> ALU ()
write Data
a forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. SDivisible a => a -> a -> a
sDiv forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Data -> ALU Value
read Data
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Data -> ALU Value
read Data
b
mod :: Data -> Data -> ALU ()
mod :: Data -> Data -> ALU ()
mod Data
a Data
b = Data -> Value -> ALU ()
write Data
a forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. SDivisible a => a -> a -> a
sMod forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Data -> ALU Value
read Data
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Data -> ALU Value
read Data
b
eql :: Data -> Data -> ALU ()
eql :: Data -> Data -> ALU ()
eql Data
a Data
b = Data -> Value -> ALU ()
write Data
a forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (Ord a, Num a, SymVal a) => SBool -> SBV a
oneIf forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. EqSymbolic a => a -> a -> SBool
(.==) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Data -> ALU Value
read Data
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Data -> ALU Value
read Data
b
run :: ALU () -> Symbolic State
run :: ALU () -> Symbolic State
run ALU ()
pgm = forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m s
ST.execStateT ALU ()
pgm State
initState
where initState :: State
initState = State { env :: Map Register Value
env = forall k a. Ord k => [(k, a)] -> Map k a
M.fromList [(Data -> Register
register Data
r, Value
0) | Data
r <- [Data
w, Data
x, Data
y, Data
z]]
, inputs :: [Value]
inputs = []
}
puzzle :: Bool -> IO ()
puzzle :: Bool -> IO ()
puzzle Bool
shouldMaximize = forall a. Show a => a -> IO ()
print forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a.
Provable a =>
SMTConfig -> OptimizeStyle -> a -> IO OptimizeResult
optimizeWith SMTConfig
z3{isNonModelVar :: Register -> Bool
isNonModelVar = (forall a. Eq a => a -> a -> Bool
/= Register
finalVar)} OptimizeStyle
Lexicographic SymbolicT IO ()
problem
where finalVar :: Register
finalVar | Bool
shouldMaximize = Register
"Maximum model number"
| Bool
True = Register
"Minimum model number"
problem :: SymbolicT IO ()
problem = do State{Map Register Value
env :: Map Register Value
env :: State -> Map Register Value
env, [Value]
inputs :: [Value]
inputs :: State -> [Value]
inputs} <- ALU () -> Symbolic State
run ALU ()
monad
forall (m :: * -> *). SolverContext m => SBool -> m ()
constrain forall a b. (a -> b) -> a -> b
$ forall a. HasCallStack => Maybe a -> a
fromJust (Data -> Register
register Data
z forall k a. Ord k => k -> Map k a -> Maybe a
`M.lookup` Map Register Value
env) forall a. EqSymbolic a => a -> a -> SBool
.== Value
0
let digits :: [Value]
digits = forall a. [a] -> [a]
reverse [Value]
inputs
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
ST.forM_ [Value]
digits forall a b. (a -> b) -> a -> b
$ \Value
d -> forall (m :: * -> *). SolverContext m => SBool -> m ()
constrain forall a b. (a -> b) -> a -> b
$ Value
d forall a. OrdSymbolic a => a -> (a, a) -> SBool
`inRange` (Value
1, Value
9)
let modelNum :: Value
modelNum = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (\Value
sofar Value
d -> Value
10 forall a. Num a => a -> a -> a
* Value
sofar forall a. Num a => a -> a -> a
+ Value
d) Value
0 [Value]
digits
if Bool
shouldMaximize
then forall a. Metric a => Register -> SBV a -> SymbolicT IO ()
maximize Register
"goal" Value
modelNum
else forall a. Metric a => Register -> SBV a -> SymbolicT IO ()
minimize Register
"goal" Value
modelNum
Value
modelNumV <- forall a. SymVal a => Register -> Symbolic (SBV a)
free Register
finalVar
forall (m :: * -> *). SolverContext m => SBool -> m ()
constrain forall a b. (a -> b) -> a -> b
$ Value
modelNumV forall a. EqSymbolic a => a -> a -> SBool
.== Value
modelNum
monad :: ALU ()
monad :: ALU ()
monad = do Data -> ALU ()
inp Data
w
Data -> Data -> ALU ()
mul Data
x Data
0
Data -> Data -> ALU ()
add Data
x Data
z
Data -> Data -> ALU ()
mod Data
x Data
26
Data -> Data -> ALU ()
div Data
z Data
1
Data -> Data -> ALU ()
add Data
x Data
11
Data -> Data -> ALU ()
eql Data
x Data
w
Data -> Data -> ALU ()
eql Data
x Data
0
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
25
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
y Data
1
Data -> Data -> ALU ()
mul Data
z Data
y
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
w
Data -> Data -> ALU ()
add Data
y Data
5
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
z Data
y
Data -> ALU ()
inp Data
w
Data -> Data -> ALU ()
mul Data
x Data
0
Data -> Data -> ALU ()
add Data
x Data
z
Data -> Data -> ALU ()
mod Data
x Data
26
Data -> Data -> ALU ()
div Data
z Data
1
Data -> Data -> ALU ()
add Data
x Data
13
Data -> Data -> ALU ()
eql Data
x Data
w
Data -> Data -> ALU ()
eql Data
x Data
0
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
25
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
y Data
1
Data -> Data -> ALU ()
mul Data
z Data
y
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
w
Data -> Data -> ALU ()
add Data
y Data
5
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
z Data
y
Data -> ALU ()
inp Data
w
Data -> Data -> ALU ()
mul Data
x Data
0
Data -> Data -> ALU ()
add Data
x Data
z
Data -> Data -> ALU ()
mod Data
x Data
26
Data -> Data -> ALU ()
div Data
z Data
1
Data -> Data -> ALU ()
add Data
x Data
12
Data -> Data -> ALU ()
eql Data
x Data
w
Data -> Data -> ALU ()
eql Data
x Data
0
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
25
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
y Data
1
Data -> Data -> ALU ()
mul Data
z Data
y
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
w
Data -> Data -> ALU ()
add Data
y Data
1
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
z Data
y
Data -> ALU ()
inp Data
w
Data -> Data -> ALU ()
mul Data
x Data
0
Data -> Data -> ALU ()
add Data
x Data
z
Data -> Data -> ALU ()
mod Data
x Data
26
Data -> Data -> ALU ()
div Data
z Data
1
Data -> Data -> ALU ()
add Data
x Data
15
Data -> Data -> ALU ()
eql Data
x Data
w
Data -> Data -> ALU ()
eql Data
x Data
0
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
25
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
y Data
1
Data -> Data -> ALU ()
mul Data
z Data
y
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
w
Data -> Data -> ALU ()
add Data
y Data
15
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
z Data
y
Data -> ALU ()
inp Data
w
Data -> Data -> ALU ()
mul Data
x Data
0
Data -> Data -> ALU ()
add Data
x Data
z
Data -> Data -> ALU ()
mod Data
x Data
26
Data -> Data -> ALU ()
div Data
z Data
1
Data -> Data -> ALU ()
add Data
x Data
10
Data -> Data -> ALU ()
eql Data
x Data
w
Data -> Data -> ALU ()
eql Data
x Data
0
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
25
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
y Data
1
Data -> Data -> ALU ()
mul Data
z Data
y
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
w
Data -> Data -> ALU ()
add Data
y Data
2
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
z Data
y
Data -> ALU ()
inp Data
w
Data -> Data -> ALU ()
mul Data
x Data
0
Data -> Data -> ALU ()
add Data
x Data
z
Data -> Data -> ALU ()
mod Data
x Data
26
Data -> Data -> ALU ()
div Data
z Data
26
Data -> Data -> ALU ()
add Data
x Data
-1
Data -> Data -> ALU ()
eql Data
x Data
w
Data -> Data -> ALU ()
eql Data
x Data
0
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
25
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
y Data
1
Data -> Data -> ALU ()
mul Data
z Data
y
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
w
Data -> Data -> ALU ()
add Data
y Data
2
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
z Data
y
Data -> ALU ()
inp Data
w
Data -> Data -> ALU ()
mul Data
x Data
0
Data -> Data -> ALU ()
add Data
x Data
z
Data -> Data -> ALU ()
mod Data
x Data
26
Data -> Data -> ALU ()
div Data
z Data
1
Data -> Data -> ALU ()
add Data
x Data
14
Data -> Data -> ALU ()
eql Data
x Data
w
Data -> Data -> ALU ()
eql Data
x Data
0
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
25
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
y Data
1
Data -> Data -> ALU ()
mul Data
z Data
y
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
w
Data -> Data -> ALU ()
add Data
y Data
5
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
z Data
y
Data -> ALU ()
inp Data
w
Data -> Data -> ALU ()
mul Data
x Data
0
Data -> Data -> ALU ()
add Data
x Data
z
Data -> Data -> ALU ()
mod Data
x Data
26
Data -> Data -> ALU ()
div Data
z Data
26
Data -> Data -> ALU ()
add Data
x Data
-8
Data -> Data -> ALU ()
eql Data
x Data
w
Data -> Data -> ALU ()
eql Data
x Data
0
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
25
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
y Data
1
Data -> Data -> ALU ()
mul Data
z Data
y
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
w
Data -> Data -> ALU ()
add Data
y Data
8
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
z Data
y
Data -> ALU ()
inp Data
w
Data -> Data -> ALU ()
mul Data
x Data
0
Data -> Data -> ALU ()
add Data
x Data
z
Data -> Data -> ALU ()
mod Data
x Data
26
Data -> Data -> ALU ()
div Data
z Data
26
Data -> Data -> ALU ()
add Data
x Data
-7
Data -> Data -> ALU ()
eql Data
x Data
w
Data -> Data -> ALU ()
eql Data
x Data
0
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
25
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
y Data
1
Data -> Data -> ALU ()
mul Data
z Data
y
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
w
Data -> Data -> ALU ()
add Data
y Data
14
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
z Data
y
Data -> ALU ()
inp Data
w
Data -> Data -> ALU ()
mul Data
x Data
0
Data -> Data -> ALU ()
add Data
x Data
z
Data -> Data -> ALU ()
mod Data
x Data
26
Data -> Data -> ALU ()
div Data
z Data
26
Data -> Data -> ALU ()
add Data
x Data
-8
Data -> Data -> ALU ()
eql Data
x Data
w
Data -> Data -> ALU ()
eql Data
x Data
0
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
25
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
y Data
1
Data -> Data -> ALU ()
mul Data
z Data
y
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
w
Data -> Data -> ALU ()
add Data
y Data
12
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
z Data
y
Data -> ALU ()
inp Data
w
Data -> Data -> ALU ()
mul Data
x Data
0
Data -> Data -> ALU ()
add Data
x Data
z
Data -> Data -> ALU ()
mod Data
x Data
26
Data -> Data -> ALU ()
div Data
z Data
1
Data -> Data -> ALU ()
add Data
x Data
11
Data -> Data -> ALU ()
eql Data
x Data
w
Data -> Data -> ALU ()
eql Data
x Data
0
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
25
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
y Data
1
Data -> Data -> ALU ()
mul Data
z Data
y
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
w
Data -> Data -> ALU ()
add Data
y Data
7
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
z Data
y
Data -> ALU ()
inp Data
w
Data -> Data -> ALU ()
mul Data
x Data
0
Data -> Data -> ALU ()
add Data
x Data
z
Data -> Data -> ALU ()
mod Data
x Data
26
Data -> Data -> ALU ()
div Data
z Data
26
Data -> Data -> ALU ()
add Data
x Data
-2
Data -> Data -> ALU ()
eql Data
x Data
w
Data -> Data -> ALU ()
eql Data
x Data
0
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
25
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
y Data
1
Data -> Data -> ALU ()
mul Data
z Data
y
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
w
Data -> Data -> ALU ()
add Data
y Data
14
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
z Data
y
Data -> ALU ()
inp Data
w
Data -> Data -> ALU ()
mul Data
x Data
0
Data -> Data -> ALU ()
add Data
x Data
z
Data -> Data -> ALU ()
mod Data
x Data
26
Data -> Data -> ALU ()
div Data
z Data
26
Data -> Data -> ALU ()
add Data
x Data
-2
Data -> Data -> ALU ()
eql Data
x Data
w
Data -> Data -> ALU ()
eql Data
x Data
0
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
25
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
y Data
1
Data -> Data -> ALU ()
mul Data
z Data
y
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
w
Data -> Data -> ALU ()
add Data
y Data
13
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
z Data
y
Data -> ALU ()
inp Data
w
Data -> Data -> ALU ()
mul Data
x Data
0
Data -> Data -> ALU ()
add Data
x Data
z
Data -> Data -> ALU ()
mod Data
x Data
26
Data -> Data -> ALU ()
div Data
z Data
26
Data -> Data -> ALU ()
add Data
x Data
-13
Data -> Data -> ALU ()
eql Data
x Data
w
Data -> Data -> ALU ()
eql Data
x Data
0
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
25
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
y Data
1
Data -> Data -> ALU ()
mul Data
z Data
y
Data -> Data -> ALU ()
mul Data
y Data
0
Data -> Data -> ALU ()
add Data
y Data
w
Data -> Data -> ALU ()
add Data
y Data
6
Data -> Data -> ALU ()
mul Data
y Data
x
Data -> Data -> ALU ()
add Data
z Data
y
{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}