recursive lockstep example
This commit is contained in:
parent
26d0d3158f
commit
e036fa16f8
15 changed files with 536 additions and 133 deletions
203
README.md
203
README.md
|
@ -79,19 +79,18 @@ box t, γ ⊢ δ
|
|||
ρ; γ ⊢ box t, δ
|
||||
|
||||
|
||||
// recursion through operators are handled using the recursion context ρ
|
||||
// XXX compare with iso-recursive subtyping (double expansion)
|
||||
---- [op-discharge]
|
||||
a [t..], ρ; γ ⊢ a [t..], δ
|
||||
|
||||
a [t..]*, ρ; γ ⊢ expand(a [t..]), δ
|
||||
---- [op-expand1]
|
||||
ρ; γ ⊢ a [t..], δ
|
||||
|
||||
a [t..], ρ; γ ⊢ expand(a [t..]), δ
|
||||
---- [op-expand2]
|
||||
a [t..]*, ρ; γ ⊢ a [t..], δ
|
||||
// using cyclic proof strategy, rule for dealing with aliases/type operators
|
||||
// becomes really simple. However, this requires well-formedness rules on types
|
||||
// to exclude typedefs like
|
||||
// type A = A
|
||||
// Or that our cycle detection excludes paths between "identical" states.
|
||||
γ ⊢ expand(a[t..]), δ
|
||||
----
|
||||
γ ⊢ a[t..], δ
|
||||
|
||||
expand(a[t..]), γ ⊢ δ
|
||||
----
|
||||
a[t..], γ ⊢ δ
|
||||
|
||||
|
||||
// member types are filtered according to member name
|
||||
|
@ -108,10 +107,12 @@ n fresh
|
|||
ρ; γ ⊢ δ
|
||||
|
||||
|
||||
|
||||
|
||||
ρ; t[n/x], s[n/y] ⊢ u[n/z]
|
||||
----
|
||||
ρ; forall x. t, forall y. s ⊢ forall z. u
|
||||
```
|
||||
|
||||
|
||||
### context operators
|
||||
|
||||
* box filtering
|
||||
|
@ -123,22 +124,50 @@ n fresh
|
|||
* member unwrapping
|
||||
```
|
||||
(t, γ) >> m =def= s, (γ >> m) if t == { m : s }, for some s
|
||||
t, (γ >> m) if t == box s, for some s
|
||||
γ >> m otherwise
|
||||
```
|
||||
|
||||
* forall-unwrapping and substitution
|
||||
```
|
||||
(t, γ) [n] =def= s [n/x], (γ [n]) if t == forall x . s, for some x, s
|
||||
t, (γ [n]) if t == box s, for some s
|
||||
γ [n] otherwise
|
||||
```
|
||||
|
||||
What happens when box is buried under type operators, like box s & box t? It
|
||||
could be that the above definition filters out too much of the contexts.
|
||||
### Recursive subtyping
|
||||
|
||||
Type aliases creates the possibility of recursive types, and thus we need to
|
||||
handle recursive subtyping
|
||||
|
||||
Handling subtyping co-inductively would enable us to handle the relation
|
||||
```
|
||||
type A = { x : { y : A } }
|
||||
type B = { y : { x : B } }
|
||||
|
||||
A <: { x : B }
|
||||
{ x : B } <: A
|
||||
```
|
||||
|
||||
|
||||
We have made progress if we "switch context"
|
||||
|
||||
If we make progress and end up at the same sequent, co-induction gives us the
|
||||
conclusion.
|
||||
|
||||
Some actions/rules lead to equivalent contexts, i.e. does not switch
|
||||
context/make progress.
|
||||
|
||||
### Other
|
||||
|
||||
True ~ { x : True } on the left
|
||||
False ~ { x : False } on the right
|
||||
|
||||
or rather
|
||||
|
||||
True ~ { x : True } in positive position
|
||||
False ~ { x : False } in negative position
|
||||
|
||||
My gut feeling™ makes me think it is just a matter of reordering sequent rules
|
||||
to get keep the things wanted in context, which for an algorithm sucks, but from
|
||||
a declarative standpoint would be okay. This needs some further validation, and
|
||||
of course a reformulation for the actual algorithm.
|
||||
|
||||
|
||||
|
||||
|
@ -154,6 +183,139 @@ if ¬s, then s => t holds
|
|||
```
|
||||
|
||||
|
||||
altho
|
||||
```
|
||||
γ ⊢ s => t, s, δ
|
||||
```
|
||||
|
||||
Given the msph program
|
||||
```
|
||||
nominal n
|
||||
|
||||
type Woops[e] = {
|
||||
member f : (e <: false => n) | (e <: false)
|
||||
}
|
||||
|
||||
type Noooes = {
|
||||
member f : true
|
||||
}
|
||||
```
|
||||
we can prove that, for any type `t`
|
||||
```
|
||||
Noooes <: Woops[t]
|
||||
```
|
||||
|
||||
The derivation looks like this:
|
||||
```
|
||||
---- [identity]
|
||||
true, t <: false ⊢ n, (t <: false)
|
||||
---- [impl-right]
|
||||
true ⊢ (t <: false => n), (t <: false)
|
||||
---- [disj-right]
|
||||
true ⊢ (t <: false => n) | (t <: false)
|
||||
---- [member]
|
||||
{ f : true } ⊢ { f : (t <: false => n) | (t <: false) }
|
||||
---- [expand-right]
|
||||
{ f : true } ⊢ Woops[t]
|
||||
---- [expand-left]
|
||||
Nooes ⊢ Woops[t]
|
||||
---- [impl-right]
|
||||
⊢ Nooes => Woops[t]
|
||||
---- [box-right]
|
||||
⊢ Nooes <: Woops[t]
|
||||
```
|
||||
|
||||
This looks a bit dangerous at first. However, if we translate the implication to
|
||||
using disjunction and negation, we get
|
||||
```
|
||||
(t <: false => N) | (t <: false) == (¬(t <: false) | n) | (t <: false)
|
||||
```
|
||||
|
||||
Considering the two cases
|
||||
```
|
||||
(1) t == false
|
||||
(2) t != false
|
||||
```
|
||||
we see that in (1)
|
||||
```
|
||||
(¬(t <: false) | n) | (t <: false) ==
|
||||
(¬(true) | n) | (true) ==
|
||||
true
|
||||
```
|
||||
and in (2)
|
||||
```
|
||||
(¬(t <: false) | n) | (t <: false) ==
|
||||
(¬(false) | n) | false ==
|
||||
(true | n) | false ==
|
||||
true
|
||||
```
|
||||
|
||||
## What is true?
|
||||
|
||||
Our "set interpretation" of types says `true` represents the full universe of
|
||||
"things".
|
||||
|
||||
What are these things?
|
||||
|
||||
For all intents and purposes, a programmer can look at them as the values of
|
||||
our language.
|
||||
|
||||
What does this mean in practical terms?
|
||||
|
||||
Well, it means something of type `true` is "a value".
|
||||
|
||||
What is "a value" then?
|
||||
|
||||
That's a good question. It can be anything really.
|
||||
|
||||
An integer?
|
||||
|
||||
Yep!
|
||||
|
||||
A function?
|
||||
|
||||
Yes, m'am!
|
||||
|
||||
A solution to the halting problem?
|
||||
|
||||
Well, yeah! But good luck constructing that.
|
||||
|
||||
A...
|
||||
|
||||
I think you get my point. A value can be anything from a simple integer to
|
||||
nuclear apocalypse. The thing is, from the point of view of our program, it
|
||||
means "we cannot really say anything here".
|
||||
|
||||
But couldn't that be dangerous?
|
||||
|
||||
Depends on what you mean by dangerous.
|
||||
|
||||
I mean, to be able to give everything a type?
|
||||
|
||||
Well, let me ask you this: do you like rat poison?
|
||||
|
||||
What? To eat?
|
||||
|
||||
Yeah!
|
||||
|
||||
Nooo, that'd be dangerous!
|
||||
|
||||
Yeah, exactly my point.
|
||||
|
||||
What?
|
||||
|
||||
You know what rat poison is obviously, despite it being dangerous?
|
||||
|
||||
Well, yeah...
|
||||
|
||||
Maybe you got it already, but my point is: rat poison is dangerous, but you
|
||||
still know about it, and its existance. So, something being dangerous does not
|
||||
mean you have this blank spot of knowledge that you just keep ignoring because
|
||||
of this perceived danger.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### interpretation of ⊢
|
||||
what is the interpretation of
|
||||
|
@ -171,3 +333,4 @@ disjunction of δ hold for k
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue