quantities in case don't need to be *exactly* the same

...as long as they are all compatible with the target.
for example, given ω.n : ℕ:
```
  case double_it? return ℕ of {
    'true  ⇒ plus n n;
    'false ⇒ n
  }
```
This commit is contained in:
rhiannon morris 2023-03-27 00:01:32 +02:00
parent f620dda639
commit 773f6372ea
5 changed files with 69 additions and 39 deletions

View file

@ -12,6 +12,7 @@ public export
interface Eq q => IsQty q where
zero, one : q
(+), (*) : q -> q -> q
lub : q -> q -> Maybe q
||| true if bindings of this quantity will be erased
||| and must not be runtime relevant
@ -19,9 +20,9 @@ interface Eq q => IsQty q where
isZero : Dec1 IsZero
zeroIsZero : IsZero zero
||| ``p `Compat` q`` if it is ok for a binding of
||| quantity `q` to be used exactly `p` times.
||| e.g. ``1 `Compat` 1``, ``1 `Compat` ω``
||| ``p `Compat` q`` if it is ok for a binding of quantity `q` to be used
||| exactly `p` times. e.g. ``1 `Compat` 1``, ``1 `Compat` ω``.
||| if ``π `lub` ρ`` exists, then both `π` and `ρ` must be compatible with it
Compat : Rel q
compat : Dec2 Compat

View file

@ -50,6 +50,13 @@ times One rh = rh
times pi One = pi
times Any Any = Any
public export
lub3 : Three -> Three -> Maybe Three
lub3 p q =
if p == Any || q == Any then Just Any
else if p == q then Just p
else Nothing
public export
data Compat3 : Rel Three where
CmpRefl : Compat3 rh rh
@ -103,6 +110,8 @@ IsQty Three where
(+) = plus
(*) = times
lub = lub3
IsZero = Equal Zero
isZero = decEq Zero
zeroIsZero = Refl