{-# LANGUAGE RebindableSyntax #-}
module Copilot.Library.Voting
( majority, aMajority ) where
import Copilot.Language
import qualified Prelude as P
majority :: (P.Eq a, Typed a) =>
[Stream a]
-> Stream a
majority :: [Stream a] -> Stream a
majority [] = String -> Stream a
forall a. String -> a
badUsage "majority: empty list not allowed"
majority (x :: Stream a
x:xs :: [Stream a]
xs) = [Stream a] -> Stream a -> Stream Word32 -> Stream a
forall a.
(Eq a, Typed a) =>
[Stream a] -> Stream a -> Stream Word32 -> Stream a
majority' [Stream a]
xs Stream a
x 1
majority' :: (P.Eq a, Typed a)
=> [Stream a] -> Stream a -> Stream Word32 -> Stream a
majority' :: [Stream a] -> Stream a -> Stream Word32 -> Stream a
majority' [] can :: Stream a
can _ = Stream a
can
majority' (x :: Stream a
x:xs :: [Stream a]
xs) can :: Stream a
can cnt :: Stream Word32
cnt =
Stream Bool -> (Stream Bool -> Stream a) -> Stream a
forall a b.
(Typed a, Typed b) =>
Stream a -> (Stream a -> Stream b) -> Stream b
local (Stream Word32
cnt Stream Word32 -> Stream Word32 -> Stream Bool
forall a. (Eq a, Typed a) => Stream a -> Stream a -> Stream Bool
== 0) Stream Bool -> Stream a
inZero
where
inZero :: Stream Bool -> Stream a
inZero zero :: Stream Bool
zero = Stream a -> (Stream a -> Stream a) -> Stream a
forall a b.
(Typed a, Typed b) =>
Stream a -> (Stream a -> Stream b) -> Stream b
local (if Stream Bool
zero then Stream a
x else Stream a
can) Stream a -> Stream a
inCan
where
inCan :: Stream a -> Stream a
inCan can' :: Stream a
can' = Stream Word32 -> (Stream Word32 -> Stream a) -> Stream a
forall a b.
(Typed a, Typed b) =>
Stream a -> (Stream a -> Stream b) -> Stream b
local (if Stream Bool
zero Stream Bool -> Stream Bool -> Stream Bool
|| Stream a
x Stream a -> Stream a -> Stream Bool
forall a. (Eq a, Typed a) => Stream a -> Stream a -> Stream Bool
== Stream a
can then Stream Word32
cntStream Word32 -> Stream Word32 -> Stream Word32
forall a. Num a => a -> a -> a
+1 else Stream Word32
cntStream Word32 -> Stream Word32 -> Stream Word32
forall a. Num a => a -> a -> a
-1) Stream Word32 -> Stream a
inCnt
where
inCnt :: Stream Word32 -> Stream a
inCnt cnt' :: Stream Word32
cnt' = [Stream a] -> Stream a -> Stream Word32 -> Stream a
forall a.
(Eq a, Typed a) =>
[Stream a] -> Stream a -> Stream Word32 -> Stream a
majority' [Stream a]
xs Stream a
can' Stream Word32
cnt'
aMajority :: (P.Eq a, Typed a) =>
[Stream a]
-> Stream a
-> Stream Bool
aMajority :: [Stream a] -> Stream a -> Stream Bool
aMajority [] _ = String -> Stream Bool
forall a. String -> a
badUsage "aMajority: empty list not allowed"
aMajority xs :: [Stream a]
xs can :: Stream a
can =
let
cnt :: Stream Word32
cnt = Stream Word32 -> [Stream a] -> Stream a -> Stream Word32
forall a.
(Eq a, Typed a) =>
Stream Word32 -> [Stream a] -> Stream a -> Stream Word32
aMajority' 0 [Stream a]
xs Stream a
can
in
(Stream Word32
cnt Stream Word32 -> Stream Word32 -> Stream Word32
forall a. Num a => a -> a -> a
* 2) Stream Word32 -> Stream Word32 -> Stream Bool
forall a. (Ord a, Typed a) => Stream a -> Stream a -> Stream Bool
> Int -> Stream Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([Stream a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Stream a]
xs)
aMajority' :: (P.Eq a, Typed a)
=> Stream Word32 -> [Stream a] -> Stream a -> Stream Word32
aMajority' :: Stream Word32 -> [Stream a] -> Stream a -> Stream Word32
aMajority' cnt :: Stream Word32
cnt [] _ = Stream Word32
cnt
aMajority' cnt :: Stream Word32
cnt (x :: Stream a
x:xs :: [Stream a]
xs) can :: Stream a
can =
Stream Word32 -> (Stream Word32 -> Stream Word32) -> Stream Word32
forall a b.
(Typed a, Typed b) =>
Stream a -> (Stream a -> Stream b) -> Stream b
local (if Stream a
x Stream a -> Stream a -> Stream Bool
forall a. (Eq a, Typed a) => Stream a -> Stream a -> Stream Bool
== Stream a
can then Stream Word32
cntStream Word32 -> Stream Word32 -> Stream Word32
forall a. Num a => a -> a -> a
+1 else Stream Word32
cnt) ((Stream Word32 -> Stream Word32) -> Stream Word32)
-> (Stream Word32 -> Stream Word32) -> Stream Word32
forall a b. (a -> b) -> a -> b
$ \ cnt' :: Stream Word32
cnt' ->
Stream Word32 -> [Stream a] -> Stream a -> Stream Word32
forall a.
(Eq a, Typed a) =>
Stream Word32 -> [Stream a] -> Stream a -> Stream Word32
aMajority' Stream Word32
cnt' [Stream a]
xs Stream a
can