Open isovector opened 3 years ago
Yeah, do
containsConstants (Add _ _) = True
instead. That will stop ghc-typelits-extra
from making judgements about addition.
That does it, cheers! PR incoming!
Does your PR handle?
test1 :: Proxy a -> Proxy b -> Proxy n -> Proxy (Max (a + n) (b + n)) -> Proxy (n + Max a b)
test1 _ _ _ = id
Nice catch --- no, it doesn't. I assumed commutativity would be handled by natnormalise?
Yeah. Sadly natnormalise
doesn't rewrite inside equality constraints.
Dang. What do you think is the move here? Use nonDetCmpType
to find a canonical ordering of plus terms?
Discovered CType
and ordered based on that; your testcase passes now!
Nice, I can live what that solution for now.
It will still fail for
test2 :: Proxy a -> Proxy b -> Proxy x -> Proxy y -> Proxy (Max (a + (x * y)) (b + (y * x)) -> Proxy ((y * x) + Max a b)
test2 _ _ _ _ = id
We can call https://hackage.haskell.org/package/ghc-typelits-natnormalise-0.7.6/docs/GHC-TypeLits-Normalise-Unify.html#v:normaliseNatEverywhere to actually use the normalise
solver inside of the extra solver where appropriate. But there are some intricacies there, so I'll simply build that on top of your PR once you've submitted it.
tl;dr: This patch doesn't actually help me in the real world. Am I expecting natnormalise to do too much?
My original use case, however, doesn't seem to work yet. The constraint I'm trying to solve:
((Max (((SizeOf word + SizeOf word) + 1) + 1)
((SizeOf word + 1) + 1)
) + 1)
<=?
((((Max (1 + (n + SizeOf word))
((Max (Max (((SizeOf word + SizeOf word) + 1) + 1)
((SizeOf word + 1) + 1) + 1)
n
) + 1
) + 1
)
) - 1) - 1))
which under natnormalise should simplify to (IIUC):
((Max (((SizeOf word + SizeOf word) + 2))
((SizeOf word + 2))
) + 1)
<=?
((((Max (1 + (n + SizeOf word))
((Max ((Max (((SizeOf word + SizeOf word) + 2))
((SizeOf word + 2))
) + 1)
n
) + 1
) + 1
)
) - 2)))
and now under the new rules, should be:
((Max (((SizeOf word + SizeOf word) + 2) + 1)
((SizeOf word + 2) + 1)
))
<=?
((((Max (1 + (n + SizeOf word) + 1 - 2)
((Max ((Max (((SizeOf word + SizeOf word) + 3) + 2 - 2)
((SizeOf word + 3) + 2 - 2)
))
(n + 2 - 2)
)
)
)
))))
and then I'd expect the subtractions to cancel:
((Max (((SizeOf word + SizeOf word) + 2) + 1)
((SizeOf word + 2) + 1)
))
<=?
((((Max ((n + SizeOf word))
((Max ((Max (((SizeOf word + SizeOf word) + 3))
((SizeOf word + 3))
))
(n)
)
)
)
))))
after some simplification by hand:
Max (SizeOf word + SizeOf word + 3)
(SizeOf word + 3)
<=?
Max (n + SizeOf word)
(Max (Max (SizeOf word + SizeOf word + 3)
(SizeOf word + 3)
) n
)
and then
(SizeOf word + SizeOf word + 3)
<=?
Max (n + SizeOf word)
(Max (SizeOf word + SizeOf word + 3) n)
Here, we have (SizeOf word + SizeOf word + 3)
on both sides, so this thing should just be True
. But the solver appears to be stuck at the first step?
I'm attempting to implement this myself, rewriting
Max a b + n
asMax (a + n) (b + n)
--- but the existing tests fail to compile when I add anormaliseNat
case for the plus constructor. Eg, the following errors are some of the sort:I guess I've broken the usual natnormalisation that goes on? Is there an easy way to get it back?
Diff: https://github.com/clash-lang/ghc-typelits-extra/compare/master...isovector:plus-max?expand=1&w=1