never executed always true always false
1 {-# LANGUAGE DeriveGeneric, DeriveDataTypeable, DeriveFunctor, DeriveTraversable, DeriveFoldable #-}
2 {-# LANGUAGE UndecidableInstances #-}
3
4 module Conjure.Language.Expression.Op.Product where
5
6 import Conjure.Prelude
7 import Conjure.Language.Expression.Op.Internal.Common
8
9 import qualified Data.Aeson as JSON -- aeson
10 import qualified Data.Aeson.KeyMap as KM
11
12 import qualified Data.Vector as V -- vector
13
14
15 data OpProduct x = OpProduct x
16 deriving (Eq, Ord, Show, Data, Functor, Traversable, Foldable, Typeable, Generic)
17
18 instance Serialize x => Serialize (OpProduct x)
19 instance Hashable x => Hashable (OpProduct x)
20 instance ToJSON x => ToJSON (OpProduct x) where toJSON = genericToJSON jsonOptions
21 instance FromJSON x => FromJSON (OpProduct x) where parseJSON = genericParseJSON jsonOptions
22
23 instance (TypeOf x, Pretty x, ExpressionLike x) => TypeOf (OpProduct x) where
24 typeOf p@(OpProduct x) = do
25 ty <- typeOf x
26 innerTy <- case ty of
27 TypeList t -> return t
28 TypeMatrix _ t -> return t
29 TypeSet t -> return t
30 TypeMSet t -> return t
31 _ -> raiseTypeError $ vcat [ pretty p
32 , "The argument has type:" <+> pretty ty
33 ]
34 case innerTy of
35 TypeAny | Just [] <- listOut x -> return (TypeInt TagInt)
36 TypeInt t | ?typeCheckerMode == RelaxedIntegerTags -> return (TypeInt t)
37 TypeInt TagInt -> return (TypeInt TagInt)
38 TypeInt t@(TaggedInt _) -> return $ TypeInt t
39 _ -> raiseTypeError $ vcat [ pretty p
40 , "The argument has type:" <+> pretty ty
41 ]
42
43 instance BinaryOperator (OpProduct x) where
44 opLexeme _ = L_Times
45
46 instance (OpProduct x :< x) => SimplifyOp OpProduct x where
47 simplifyOp (OpProduct x)
48 | Just xs <- listOut x
49 , let filtered = filter (/=0) xs
50 , length filtered /= length xs -- there were 0's
51 = return 0
52 simplifyOp (OpProduct x)
53 | Just xs <- listOut x
54 , let filtered = filter (/=1) xs
55 , length filtered /= length xs -- there were 1's
56 = case filtered of
57 [] -> return 1
58 [n] -> return n
59 _ -> return $ inject $ OpProduct $ fromList filtered
60 simplifyOp _ = na "simplifyOp{OpProduct}"
61
62 instance (Pretty x, ExpressionLike x) => Pretty (OpProduct x) where
63 prettyPrec prec op@(OpProduct x) | Just [a,b] <- listOut x = prettyPrecBinOp prec [op] a b
64 prettyPrec _ (OpProduct x) = "product" <> prParens (pretty x)
65
66 instance (VarSymBreakingDescription x, ExpressionLike x) => VarSymBreakingDescription (OpProduct x) where
67 varSymBreakingDescription (OpProduct x) | Just xs <- listOut x = JSON.Object $ KM.fromList
68 [ ("type", JSON.String "OpProduct")
69 , ("children", JSON.Array $ V.fromList $ map varSymBreakingDescription xs)
70 , ("symmetricChildren", JSON.Bool True)
71 ]
72 varSymBreakingDescription (OpProduct x) = JSON.Object $ KM.fromList
73 [ ("type", JSON.String "OpProduct")
74 , ("children", varSymBreakingDescription x)
75 ]