8000 Subtyping: Transitivity of opt-to-constituent rule · Issue #146 · dfinity/candid · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Subtyping: Transitivity of opt-to-constituent rule #146

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

Closed
nomeata opened this issue Dec 3, 2020 · 5 comments
Closed

Subtyping: Transitivity of opt-to-constituent rule #146

nomeata opened this issue Dec 3, 2020 · 5 comments

Comments

@nomeata
Copy link
Collaborator
nomeata commented Dec 3, 2020

I started to do some baby steps in formalizing a “mini candid” in Coq, starting with the rules that seem safe.

But adding the “specialize to constituent type” rule is causing problems:

If the rule is

not (null <: t2)     t1 <: t2
--------------------------------
        t1 <: opt t2

as it is now, then this is not transitive. We have int <: opt int (by this rule), opt int <: opt opt int (by the normal rule), but not int <: opt opt int (because of the not (null <: t2) restriction).

This restriction was added in #135, upon my suggestion. Without that restriction, we have the problems described in #135, i.e. bad interaction with the “catch decoding rule”, and the problem that

    t1 <: t2
------------------
  t1 <: opt t2

doesn't make progress if t2 = opt t2.

Or, to respond to @rossberg says in #135 (comment)

Interesting suggestion. I suppose options of options are not something you would see often in an interface, so limiting their evolution might be okay. How confident can we be that this has no problems?

I wish we had spare cycles to mechanise this, and prevent further holes.

I am no longer confident that this has no problems.

One way to maybe! taper over the problem is to restrict the other rule as well:

not (null <: t2)     t1 <: t2
--------------------------------
     opt  t1 <: opt t2

so that you can’t go from opt int to opt opt int… but that essentially disallows evolution under opt opt and might be better served by disallowing opt opt… probably not nice. Or maybe this rule:

(null <: t1) iff (null <: 2)      t1 <: t2
---------------------------------------
             opt  t1 <: opt t2

which rules out opt int <: opt opt int without ruling out opt nat <: opt int nor opt opt nat <: opt opt int ?

@nomeata
Copy link
Collaborator Author
nomeata commented Dec 3, 2020

Maybe this is all fine together with the other special behavior for opt (the opportunistic decoding). But that one is dubious for other reasons, see #141. And even if it is fine, I wonder if we get weird transitive behavior.

nomeata added a commit that referenced this issue Dec 3, 2020
starting a bit on a Candid formalization, focusing on the
Opt-to-constituent rule.

Stuck at #146,
and worked around by adding restrictions to the compositional rule for
opt.
@nomeata nomeata mentioned this issue Dec 3, 2020
@nomeata
Copy link
Collaborator Author
nomeata commented Dec 3, 2020

With the extra (null <: t1) iff (null <: 2) restriction, I can prove transitivity, see #147. Hmm, not sure I like that.

@crusso
Copy link
Contributor
crusso commented Dec 4, 2020

What if you have (dynamic) maybe and vanilla opt and restrict maybe to be invariant. That rules out the counterexample, I think, but maybe too much else...

@nomeata
Copy link
Collaborator Author
nomeata commented Dec 4, 2020

This issue here isn't really about the dynamic aspects of opt, it already arises with the desire to do t <: opt t. A separate type constructor might help if we forbid its immediate nesting (no maybe maybe t).

@nomeata
Copy link
Collaborator Author
nomeata commented Dec 11, 2020

Closing this; the narrow issue of this issue only applies to a variant of the formalism that we are not using right now, as the Coq profs in #147 shows (i.e. the opportunistic subtyping rule tapers over this problem.)

@nomeata nomeata closed this as completed Dec 11, 2020
nomeata added a commit that referenced this issue Jan 19, 2021
This contains an initial formalization of Candid in Coq. It covers these types:
`nat`, `int`, `null`, `opt t`, `empty`, `reserved`

It considers two different formalisms:

* `NoOpportunisticDecoding`
  This is without `t <: opt t'`, but with `t <: opt t`.
  Things go through, although the `opt t <: opt t'` rule has to be tweaked to keep subtyping transitive (see #146).

* `OpportunisticDecoding`
  This is with `t <: opt t'`.
  Because of the negative hypotheses in the coercion relation, this can’t be defined as a simple inductive relation (which is a seroius smell!).
  So instead I define it as a function (which is mostly straight forward), and prove the properties there.
  We _could_ take this as indication that maybe our spec should also just define it via equations. We don’t gain anything from the relational presentation, I think, and implementors all anyways implement functions.
  Nevertheless, I did prove that the relation defined by admits the intro and induction rules that _would_ come out of the inductive relation (ignoring the negative hypotheses). This revealed some issues with the way the rules are presented, will create a PR for that soon.

In both cases, I prove
 * Correctness of decoding
 * Roundtripping
 * Uniqueness of decoding
 * Soundness of subtyping
 * Transitivity of subtyping

I do _not_ prove Higher-order soundness, because we know it does not hold (see #141).

This also uses some proof-of-concept “named Coq cases“ feature, see https://www.joachim-breitner.de/blog/777-Named_goals_in_Coq.
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

No branches or pull requests

2 participants
0