prfn utf8_c2_set
{c:int; UTF8_C2_LOWER <= c; c <= UTF8_C2_UPPER} ():
UTF8_C2(2, c) =
let
stacst b1:hb_C2
stadef c1:int = b1 - 0xC0
stacst b2:tb_80
stadef c2:int = (c1 * 64) + (b2 - 0x80)
prval pfd1:DATA(1, b1) = FIRST
prval pfc1:UTF8_C2(1, c1) = UTF8_C2_1(pfd1)
prval pfd2:DATA(2, b2) = NEXT(pfd1)
prval pfc2:UTF8_C2(2, c2) = UTF8_C2_2(pfc1, pfd2)
in pfc2 end
prfn utf8_c2_set
{c2:int; UTF8_C2_LOWER <= c2; c2 <= UTF8_C2_UPPER}
{b1:hb_C2; c1:int; b2:tb_80}
{c1 == b1 - 0xC0; c2 == (c1 * 64) + (b2 - 0x80)}
(): UTF8_C2(2, c2) =
let
prval pfd1:DATA(1, b1) = FIRST
prval pfc1:UTF8_C2(1, c1) = UTF8_C2_1(pfd1)
prval pfd2:DATA(2, b2) = NEXT(pfd1)
prval pfc2:UTF8_C2(2, c2) = UTF8_C2_2(pfc1, pfd2)
in pfc2 end
prval [b1:int] pfd1:DATA(1, b1) = FIRST
If you show me the type of FIRST, I could probably say more.prval [b1:int] (pfd1:DATA(1, b1)) = FIRST
To get the skolem constant, please doprval [b1:int] pfd1:DATA(1, b1) = FIRST
If you show me the type of FIRST, I could probably say more.
Use this instead:prval [b1:int] (pfd1:DATA(1, b1)) = FIRST
Use this instead:prval [b1:int] (pfd1:DATA(1, b1)) = FIRST
prval [b1:hb_C2] pfd1:DATA(1, b1) = FIRST
prval pfc1:UTF8_C2(1, c1) = UTF8_C2_1(pfd1)
| {b:hb_C2; i == 1} UTF8_C2_1(i, b - 0xC0) of BYTE
There is a lot missing information.
How is hb_C2 defined?
What is the type of FIRST?
sortdef hb_C2 = {b:int | 0xC2 <= b && b <= 0xDF}
dataprop DATA (i:int, b:int) =
| FIRST(1, b)
| NEXT(i, b) of [pb:int] DATA(i-1, pb)
prfn utf8_c2_set
{c:int; UTF8_C2_LOWER <= c; c <= UTF8_C2_UPPER} ():
UTF8_C2(2, c) =
let
prval pfd1:DATA(1, b1) = FIRST
prval pfd2:DATA(2, b2) = NEXT(pfd1)
prval pf =
sif (0xC2 <= b1 && b1 <= 0xDF) && (0x80 <= b2 && b2 <= 0xBF) then
let
prval pfc1:UTF8_C2(1, c1) = UTF8_C2_1(pfd1)
prval pfc2:UTF8_C2(2, c2) = UTF8_C2_2(pfc1, pfd2)
in pfc2 end
else
// Don't know what to put here
// This won't be a valid UTF8_C2(2, c)
// There is no constnt meaning “Impossible”
in pf end
sortdef byte = {a:nat | a <= 0xFF}
dataprop DATA (int, int) =
| {b:byte} FIRST(1, b)
| {i:int;i >= 2}{b,pb:byte} NEXT(i, b) of DATA(i-1, pb)
prfn
utf8_c2_set
{c:int;
UTF8_C2_LOWER <= c;
c <= UTF8_C2_UPPER}
(
) : UTF8_C2(2, c) =
let
stadef b1 = c/64+0xC0
stadef b2 = c%64+0x80
prval pfd1 = FIRST{b1}()
in
UTF8_C2_2(UTF8_C2_1(pfd1), NEXT{2}{b2,b1}(pfd1))
end
The following code typechecks:
I suggest:
sortdef byte = {a:nat | a <= 0xFF}
dataprop DATA (int, int) =
| {b:byte} FIRST(1, b)
| {i:int;i >= 2}{b,pb:byte} NEXT(i, b) of DATA(i-1, pb)
If you write DATA(i:int, b:int), then the quantifier {i:int;b:int} is
automatically added to the front of the type of each constructor
associated with DATS.
prfn utf8_c2_set
{c:int; UTF8_C2_LOWER <= c; c <= UTF8_C2_UPPER} ():
UTF8_C2(2, c) =
let
stadef b1 = c / 64 + 0xC0
stadef b2 = c % 64 + 0x80
prval pfd1:DATA(1, b1) = FIRST
prval pfd2:DATA(2, b2) = NEXT(pfd1)
prval pfc1 = UTF8_C2_1(pfd1)
prval pfc2 = UTF8_C2_2(pfc1, pfd2)
in pfc2 end
Mainly, look at the `stacst` and `stadef` in the first version: I had to move it all as constraints outside of the body, while it should be constraints on local constants.
Use this instead:prval [b1:int] (pfd1:DATA(1, b1)) = FIRST
typedef t = [i:int] int(i)
val [i:int] (a:t) = 0:t
Subsorts can only be used together with quantification as a form of convenience.
// Just a picture, can't really do this, not allowed.
stacst b1: {b:int | b >= 0xC2 && b < 0xDF}
stacst b2: {b:int | b >= 0x80 && b < 0xBF}
stadef b1 = c / 64 + 0xC0 // Ends to be in 0xC2 .. 0xDF
stadef b2 = c % 64 + 0x80 // Ends to be in 0x80 .. 0xBF
// Same ranges, however with a relation between both!
extern
prfun
lemma
(
// argless
) : [b:int | b >= 0xC2 && b < 0xDF] void
prval [b1:int] () = lemma()
[…]
But the proof function was saying the other way: given all values in a character range, they can always be represented with this form of UTF-8 string. And for this, a relation between b1 and b2 was required, as c imposes this relation. So your way was the only one possible for this proof functions:
[…]
dataprop P =
| P1
dataprop Q =
| Q1 of P
prfn pf (p:P): Q = Q1(p)
// For the picture, not possible!
prfn pf (q:Q): [p:P; q == Q1(p)] void
prfn Q2P (pf: Q): P =
let val Q1(pf2) = pf in pf2 end
From Q to P:
prfn Q2P (pf: Q): P =
let val Q1(pf2) = pf in pf2 end
prfn Q2P (pf:Q): P =
case+ pf of
| Q1(pf2) => pf2