{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE Trustworthy #-}
module Plutus.OnChain.Bits (
xor
, odd
, even
) where
import PlutusTx.Prelude hiding (even)
{-# INLINABLE xor #-}
xor :: Integer
-> Integer
-> Integer
xor :: Integer -> Integer -> Integer
xor = Integer -> Integer -> Integer -> Integer -> Integer
xor' Integer
1 Integer
0
where
xor' :: Integer
-> Integer
-> Integer
-> Integer
-> Integer
xor' :: Integer -> Integer -> Integer -> Integer -> Integer
xor' Integer
m Integer
z Integer
x Integer
y
| Integer
x Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 = Integer
z Integer -> Integer -> Integer
forall a. AdditiveSemigroup a => a -> a -> a
+ Integer
m Integer -> Integer -> Integer
forall a. MultiplicativeSemigroup a => a -> a -> a
* Integer
y
| Integer
y Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 = Integer
z Integer -> Integer -> Integer
forall a. AdditiveSemigroup a => a -> a -> a
+ Integer
m Integer -> Integer -> Integer
forall a. MultiplicativeSemigroup a => a -> a -> a
* Integer
x
| Integer -> Bool
even Integer
x Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Integer -> Bool
even Integer
y = Integer -> Integer -> Integer -> Integer -> Integer
xor' (Integer
2 Integer -> Integer -> Integer
forall a. MultiplicativeSemigroup a => a -> a -> a
* Integer
m) Integer
z (Integer
x Integer -> Integer -> Integer
`divide` Integer
2) (Integer
y Integer -> Integer -> Integer
`divide` Integer
2)
| Bool
otherwise = Integer -> Integer -> Integer -> Integer -> Integer
xor' (Integer
2 Integer -> Integer -> Integer
forall a. MultiplicativeSemigroup a => a -> a -> a
* Integer
m) (Integer
z Integer -> Integer -> Integer
forall a. AdditiveSemigroup a => a -> a -> a
+ Integer
m) (Integer
x Integer -> Integer -> Integer
`divide` Integer
2) (Integer
y Integer -> Integer -> Integer
`divide` Integer
2)
{-# INLINABLE even #-}
even :: Integer
-> Bool
even :: Integer -> Bool
even Integer
x = Integer
x Integer -> Integer -> Integer
`modulo` Integer
2 Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0
{-# INLINABLE odd #-}
odd :: Integer
-> Bool
odd :: Integer -> Bool
odd Integer
x = Integer
x Integer -> Integer -> Integer
`modulo` Integer
2 Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
1