Skip to content

Commit c957849

Browse files
signum_ is doable, abs_ isn't super neat
1 parent b0afaa9 commit c957849

File tree

1 file changed

+10
-14
lines changed

1 file changed

+10
-14
lines changed

src/Constrained/NumOrd.hs

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
688696
data 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

695702
deriving 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

704710
instance Semantics IntW where
705711
semantics AddW = (+)
706712
semantics NegateW = negate
707713
semantics MultW = (*)
708-
semantics AbsW = abs
709714
semantics SignumW = signum
710715

711716
instance Syntax IntW where
712717
isInfix AddW = True
713718
isInfix NegateW = False
714719
isInfix MultW = True
715-
isInfix AbsW = False
716720
isInfix SignumW = False
717721

718722
class 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

874878
invertMult :: (HasSpec a, Num a, HasDivision a) => a -> a -> Maybe a
875879
invertMult 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 *.
940940
negate_ :: NumLike a => Term a -> Term a
941941
negate_ = appTerm NegateW
942942

943-
-- | `Term`-level `abs`
944-
abs_ :: NumLike a => Term a -> Term a
945-
abs_ = appTerm AbsW
946-
947943
-- | `Term`-level `signum`
948944
signum_ :: NumLike a => Term a -> Term a
949945
signum_ = appTerm SignumW

0 commit comments

Comments
 (0)