@@ -684,12 +684,19 @@ class (Num a, HasSpec a, HasDivision a, OrdLike a) => NumLike a where
684684 Maybe a
685685 safeSubtract a b = fromSimpleRep <$> safeSubtract @ (SimpleRep a ) (toSimpleRep a) (toSimpleRep b)
686686
687- -- | Operations on numbers
687+ -- | Operations on numbers.
688+ -- The reason there is no implementation of abs here is that you can't easily deal with abs
689+ -- without specifications becoming very large. Consider the following example:
690+ -- > constrained $ \ x -> [1000 <. abs_ x, abs_ x <. 1050]
691+ -- The natural `Specification` here would be something like `(-1050, -1000) || (1000, 1050)`
692+ -- - the disjoint union of two open, non-overlapping, intervals. However, this doesn't work
693+ -- because number type-specs only support a single interval. You could fudge it in all sorts of ways
694+ -- by using `chooseSpec` or by using the can't set (which would blow up to be 2000 elements large in this
695+ -- case). In short, there is no _satisfactory_ solution here.
688696data IntW (as :: [Type ]) b where
689697 AddW :: NumLike a => IntW '[a , a ] a
690698 MultW :: NumLike a => IntW '[a , a ] a
691699 NegateW :: NumLike a => IntW '[a ] a
692- AbsW :: NumLike a => IntW '[a ] a
693700 SignumW :: NumLike a => IntW '[a ] a
694701
695702deriving instance Eq (IntW dom rng )
@@ -698,21 +705,18 @@ instance Show (IntW d r) where
698705 show AddW = " +"
699706 show NegateW = " negate_"
700707 show MultW = " *"
701- show AbsW = " abs_"
702708 show SignumW = " signum_"
703709
704710instance Semantics IntW where
705711 semantics AddW = (+)
706712 semantics NegateW = negate
707713 semantics MultW = (*)
708- semantics AbsW = abs
709714 semantics SignumW = signum
710715
711716instance Syntax IntW where
712717 isInfix AddW = True
713718 isInfix NegateW = False
714719 isInfix MultW = True
715- isInfix AbsW = False
716720 isInfix SignumW = False
717721
718722class HasDivision a where
@@ -868,8 +872,8 @@ instance NumLike a => Num (Term a) where
868872 negate = negate_
869873 fromInteger = Lit . fromInteger
870874 (*) = (*.)
871- abs = abs_
872875 signum = signum_
876+ abs = error " No implementation for abs @(Term a)"
873877
874878invertMult :: (HasSpec a , Num a , HasDivision a ) => a -> a -> Maybe a
875879invertMult a b =
@@ -887,7 +891,6 @@ instance Logic IntW where
887891 | otherwise = ErrorSpec $ NE. fromList [ " zero" ]
888892 propagateTypeSpec MultW (HOLE :<: i) ts cant = divideSpec i ts <> notMemberSpec (mapMaybe (flip invertMult i) cant)
889893 propagateTypeSpec MultW ctx ts cant = propagateTypeSpec MultW (flipCtx ctx) ts cant
890- propagateTypeSpec AbsW (Unary HOLE ) ts cant = error " TODO"
891894 propagateTypeSpec SignumW (Unary HOLE ) ts cant =
892895 constrained $ \ x ->
893896 [ x `satisfies` notMemberSpec [0 ] | not $ ok 0 ] ++
@@ -911,9 +914,6 @@ instance Logic IntW where
911914 | otherwise = ErrorSpec $ NE. fromList [ " zero" ]
912915 propagateMemberSpec MultW (HOLE :<: i) es = memberSpec (mapMaybe (flip invertMult i) (NE. toList es)) (NE. fromList [" propagateSpec" ])
913916 propagateMemberSpec MultW ctx es = propagateMemberSpec MultW (flipCtx ctx) es
914- propagateMemberSpec AbsW (Unary HOLE ) es
915- | all ((== - 1 ) . signum ) es = ErrorSpec $ NE. fromList [ " abs for all negative member spec" , show es ]
916- | otherwise = MemberSpec $ NE. nub . NE. fromList $ concat $ [ [e, negate e] | e <- NE. toList es, signum e /= - 1 ]
917917 propagateMemberSpec SignumW (Unary HOLE ) es
918918 | all ((`notElem` [- 1 , 0 , 1 ]) . signum ) es = ErrorSpec $ NE. fromList [ " signum for invalid member spec" , show es ]
919919 | otherwise = constrained $ \ x ->
@@ -940,10 +940,6 @@ infixl 7 *.
940940negate_ :: NumLike a => Term a -> Term a
941941negate_ = appTerm NegateW
942942
943- -- | `Term`-level `abs`
944- abs_ :: NumLike a => Term a -> Term a
945- abs_ = appTerm AbsW
946-
947943-- | `Term`-level `signum`
948944signum_ :: NumLike a => Term a -> Term a
949945signum_ = appTerm SignumW
0 commit comments