Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Demote compare #1267

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft

Demote compare #1267

wants to merge 5 commits into from

Conversation

robdockins
Copy link
Contributor

Add primitives for computing value-level results from comparing number types.

These allow users to test equalites between type variables and
branch on the results.  This could nearly be accomplished by
instead demoting the value of the numeric expressions to integers
and comparing them as integers.  However, this required `fin`
constraints on the expressions, which is sometimes undesirable.

We also implement the `coerceSize` operation discussed in
issue #704.  We may decide to make this a primitive at a
later time.
@robdockins robdockins requested a review from yav August 20, 2021 20:46
* 'True' when 'm <= n' and 'False' otherwise.
*/
primitive compareLeq : { m : #, n : # } Bit

/**
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the interest of keeping the number of primitives down, I wonder if it might be better to add a single demoteNumeric primitve? Perhaps something like this:

demoteNumeric : { m : # } => (Bool,Integer)

The first component indicates if the number is infinite, so finite numbers would be of the form (false,n) and infinity would be (true,0). I guess it would be prettier to expose InfNat, but I am not sure it is worth the extra work.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was envisioning a demoteConstraint that takes logic about inf into account.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I was able to get isPrefix to work, so perhaps we only need a narrow solution for cases like coerceSize?

isPrefix : {m, n, a} (fin n, Eq a) => [m]a -> [n]a -> Bit
isPrefix xs x =
    if `(min n m) < `n then False
    else and [ xi == xsi | xi <- x | xsi <- xs ]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, that trick with min is interesting. We can probably reduce everything we want to do down to just the compareEq primitive with clever uses of min and max. Or, Iavor's idea would also work.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, demoteConstraint as a primitive seems tricky, as it is not clear what would be its type. I think for now we should go with a simpler solution, and the "proper" fix would be to add a GADT style language construct for examining numeric types.

@robdockins robdockins marked this pull request as draft September 14, 2021 22:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants