Skip to content

Commit

Permalink
Add axiom euclid3 (#171)
Browse files Browse the repository at this point in the history
For those thinking, "isn't it somewhat arrogant to write a Hedgehog test
for Euclid's third axiom?", rest assured I accidentally mixed up `c` and
`b` and only found out thanks to the test.
  • Loading branch information
martijnbastiaan committed Nov 11, 2022
1 parent 07a00e7 commit ef86c50
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 4 deletions.
5 changes: 5 additions & 0 deletions bittide/src/Data/Constraint/Nat/Extra.hs
Expand Up @@ -56,3 +56,8 @@ leMaxRight = unsafeCoerce (Dict :: Dict ())
-- | if (1 <= a) and (1 <= b) then (1 <= DivRU a b)
strictlyPositiveDivRu :: forall a b . (1 <= a, 1 <= b) => Dict (1 <= DivRU a b)
strictlyPositiveDivRu = unsafeCoerce (Dict :: Dict ())

-- | Euclid's third axiom: /If equals be subtracted from equals, the remainders
-- are equal/.
euclid3 :: forall a b c . (a + b <= c) => Dict (a <= c - b)
euclid3 = unsafeCoerce (Dict :: Dict ())
24 changes: 20 additions & 4 deletions bittide/tests/Tests/Haxioms.hs
Expand Up @@ -24,13 +24,14 @@ haxiomsGroup = testGroup "Haxioms"
, testPropertyNamed "leMaxLeft holds" "prop_leMaxLeft" prop_leMaxLeft
, testPropertyNamed "leMaxRight holds" "prop_leMaxRight" prop_leMaxRight
, testPropertyNamed "divWithRemainder holds" "prop_divWithRemainder" prop_divWithRemainder
, testPropertyNamed "euclid3 holds" "prop_euclid3" prop_euclid3
]

-- | Given that naturals in this module are used in proofs, we don't bother
-- generating very large ones.
--
-- | Generate a 'Natural' greater than or equal to /n/. Can generate 'Natural's
-- up to /n+1000/. This should be enough, given that naturals in this module are
-- used in proofs.
genNatural :: Natural -> Gen Natural
genNatural min_ = Gen.integral (Range.linear min_ 1000)
genNatural min_ = Gen.integral (Range.linear min_ (1000 + min_))

-- | Like 'CLog', but at term-level. Operates on 'Double's internally, so it will
-- probably fail on very large naturals. This is irrelevant for this module though,
Expand Down Expand Up @@ -152,3 +153,18 @@ prop_divWithRemainder = property $ do
b <- forAll (genNatural 1)
c <- forAll (Gen.integral (Range.linear 0 (b - 1)))
((a * b) + c) `div` b === a

-- | Test whether the following equation holds:
--
-- a <= c - b
--
-- Given:
--
-- a + b <= c
--
prop_euclid3 :: Property
prop_euclid3 = property $ do
a <- forAll (genNatural 0)
b <- forAll (genNatural 0)
c <- forAll (genNatural (a + b))
(a + b <= c) === (a <= c - b)

0 comments on commit ef86c50

Please sign in to comment.