Forgot to have 'a * 'a in child deques, but this requires having a different constructor in cases that were unified
This commit is contained in:
parent
fa3ed3b3da
commit
1bac86494b
114
deques.ml
114
deques.ml
|
@ -19,7 +19,7 @@ module Colors = struct
|
||||||
type 'a red = [ buffer0 | 'a buffer5]
|
type 'a red = [ buffer0 | 'a buffer5]
|
||||||
(* In addition to the colors defined by Kaplan and Tarjan, we define the
|
(* In addition to the colors defined by Kaplan and Tarjan, we define the
|
||||||
shorhand "empty" for buffers of size zero (which are used later on). *)
|
shorhand "empty" for buffers of size zero (which are used later on). *)
|
||||||
type empty = [ | buffer0]
|
type empty = buffer0
|
||||||
end
|
end
|
||||||
open Colors
|
open Colors
|
||||||
|
|
||||||
|
@ -40,111 +40,31 @@ module ColorOrder = struct
|
||||||
end
|
end
|
||||||
open ColorOrder
|
open ColorOrder
|
||||||
|
|
||||||
(** jacm-final.pdf p.9 (585) §4.1 media 60 134 368 36 *)
|
(** jacm-final.pdf p.9 (585) §4.1 media 60 146 368 24 *)
|
||||||
module BufferColors = struct
|
module BufferColors = struct
|
||||||
type 'a buffer = ['a green | 'a yellow | 'a red]
|
type 'a buffer = ['a green | 'a yellow | 'a red]
|
||||||
end
|
end
|
||||||
open BufferColors
|
open BufferColors
|
||||||
|
|
||||||
(** jacm-final.pdf p.8 / 584 §4.1 60 408 368 48 *)
|
(** jacm-final.pdf p.8 (584) §4.1 media 60 408 368 48 *)
|
||||||
module Deques = struct
|
module Deques = struct
|
||||||
(* We use polymorphic variants instead of the usual 't option so that it is
|
(* We use polymorphic variants instead of the usual 't option so that it is
|
||||||
possible later to indicate in which contexts a deque must or must not
|
possible later to indicate in which contexts a deque must or must not
|
||||||
have a non-empty child. *)
|
have a non-empty child. *)
|
||||||
type 'a deque = {
|
|
||||||
prefix: 'a buffer;
|
|
||||||
child: [`Child of ('a * 'a) deque | `NoChild];
|
|
||||||
suffix: 'a buffer;
|
|
||||||
}
|
|
||||||
(* We can't easily factor this, as OCaml cannot inline polymorphic variants
|
|
||||||
before they are completely defined. *)
|
|
||||||
type 'a child = [`Child of ('a * 'a) deque]
|
|
||||||
type noChild = [`NoChild]
|
|
||||||
let prefix d = d.prefix
|
|
||||||
let child d = d.child
|
|
||||||
let suffix d = d.suffix
|
|
||||||
end
|
|
||||||
open Deques
|
|
||||||
|
|
||||||
(* If we naively translate Kaplan and Tarjan's constraints into a set of
|
|
||||||
polymorphic variants, we might end up with some variation of the following,
|
|
||||||
which describes the type of a (semi-)regular stack of deques, where the
|
|
||||||
stack's pointers are one of the fields of its elements. This first attempt
|
|
||||||
only implements a single stack of deques, not a stack of substacks (where
|
|
||||||
the elements of the stack are linked by one of two pointers). *)
|
|
||||||
module DequesColors = struct
|
|
||||||
type ('prefix, 'child, 'suffix) deque = {
|
|
||||||
prefix: 'prefix;
|
|
||||||
child: 'child;
|
|
||||||
suffix: 'suffix;
|
|
||||||
}
|
|
||||||
(** jacm-final.pdf p.9 (585) §4.1 media 60 230 368 48 *)
|
|
||||||
type ('color, 'geColor, 'child) min = [
|
|
||||||
`LeftMin of ('color, [`Child of 'child | `NoChild], 'geColor) deque
|
|
||||||
| `RightMin of ('geColor, [`Child of 'child | `NoChild], 'color) deque
|
|
||||||
(* When the 'color is red, the two cases below are partially redundant
|
|
||||||
with the ones above. For example, a buffer0,`NoChild,buffer5 dequeue
|
|
||||||
could be labeled as `RightOnly or `LeftMin or `RightMin. This does not
|
|
||||||
affect the safety properties, but it would be nicer if we had an
|
|
||||||
unambiguous labeling. *)
|
|
||||||
| `LeftOnly of ('color, [ `NoChild], empty) deque
|
|
||||||
| `RightOnly of ( empty, [ `NoChild], 'color) deque
|
|
||||||
]
|
|
||||||
|
|
||||||
(** jacm-final.pdf p.9 (585) §4.1 media 60 290 368 60 *)
|
|
||||||
(* If we try to inline and merge together polymorphic variants (e.g. ['a
|
|
||||||
greenDeque|'yellowGDeque]) which are defined as mutually-recursive types,
|
|
||||||
OCamle gives the following error: *)
|
|
||||||
(* "Error: The type constructor yellowDeque is not yet completely defined"
|
|
||||||
We therefore first define the types by moving the [`X of …] at the
|
|
||||||
use-site, and stripping it away from the definition site. Then, we wrap
|
|
||||||
the types defined that way in order to put back the [`X of …] around each
|
|
||||||
type. *)
|
|
||||||
(* Since OCaml does not allow types to be shadowed, we define the first
|
|
||||||
unwrapped version of the types in a submodule. Types which are made
|
|
||||||
available in the current scope by using "open" can be shadowed by later
|
|
||||||
uses of "open" and later definitions. *)
|
|
||||||
module ToFixup = struct
|
|
||||||
type 'a greenDeque = ('a green, 'a geGreen, [ `Green of 'a greenDeque
|
|
||||||
| `Yellow of 'a yellowGRDeque
|
|
||||||
| `Red of 'a redDeque ]) min
|
|
||||||
and 'a yellowGDeque = ('a yellow, 'a geYellow, [ `Green of 'a greenDeque
|
|
||||||
| `Yellow of 'a yellowGDeque ]) min
|
|
||||||
and 'a yellowGRDeque = ('a yellow, 'a geYellow, [ `Green of 'a greenDeque
|
|
||||||
| `Yellow of 'a yellowGRDeque
|
|
||||||
| `Red of 'a redDeque ]) min
|
|
||||||
and 'a redDeque = ('a red, 'a geRed, [ `Green of 'a greenDeque
|
|
||||||
| `Yellow of 'a yellowGDeque ]) min
|
|
||||||
end
|
|
||||||
open ToFixup
|
|
||||||
type nonrec 'a greenDeque = [`Green of 'a greenDeque]
|
|
||||||
type nonrec 'a yellowGDeque = [`Yellow of 'a yellowGDeque]
|
|
||||||
type nonrec 'a yellowGRDeque = [`Yellow of 'a yellowGRDeque]
|
|
||||||
type nonrec 'a redDeque = [`Red of 'a redDeque]
|
|
||||||
|
|
||||||
(** * jacm-final.pdf p.9 (585) §4.1 media 60 290 368 60 *)
|
|
||||||
type 'a semiregular = ['a greenDeque | 'a yellowGRDeque | 'a redDeque]
|
|
||||||
(** * jacm-final.pdf p.9 (585) §4.1 media 60 338 368 24 *)
|
|
||||||
type 'a regular = ['a greenDeque | 'a yellowGDeque | 'a redDeque]
|
|
||||||
end
|
|
||||||
open DequesColors
|
|
||||||
|
|
||||||
(* As we can see, the above translation defines the semiregular and regular
|
|
||||||
types as a variant of variants, with 10 cases in total in the
|
|
||||||
definition. Substacks will introduce a number of corner cases, and the
|
|
||||||
above definition could become a long list of those. *)
|
|
||||||
(* Instead, we choose to separate the concerns related to pairs of buffers,
|
|
||||||
substacks and stacks. Each level of the construction has its own corner
|
|
||||||
cases, which will be to some extent kept separate. We first start by
|
|
||||||
updating the definition of deques so that the stack becomes a separate,
|
|
||||||
apparent structure. *)
|
|
||||||
module DequesColorsStack = struct
|
|
||||||
type ('prefix, 'substack, 'suffix) deque = {
|
type ('prefix, 'substack, 'suffix) deque = {
|
||||||
prefix: 'prefix;
|
prefix: 'prefix;
|
||||||
substack: 'substack;
|
substack: 'substack;
|
||||||
suffix: 'suffix}
|
suffix: 'suffix}
|
||||||
|
type 'a child = 'a * 'a
|
||||||
|
end
|
||||||
|
open Deques
|
||||||
|
|
||||||
|
module DequesColorsStack = struct
|
||||||
|
|
||||||
(** jacm-final.pdf p.9 (585) §4.1 media 60 230 368 48 *)
|
(** jacm-final.pdf p.9 (585) §4.1 media 60 230 368 48 *)
|
||||||
|
(* TODO: this is ambiguous: when the colors are the same, or for the empty
|
||||||
|
cases, several constructors could be used for the same pair of
|
||||||
|
buffers. *)
|
||||||
type ('color, 'geColor, 'substack) min = [
|
type ('color, 'geColor, 'substack) min = [
|
||||||
`LeftMin of ('color, 'substack, 'geColor) deque
|
`LeftMin of ('color, 'substack, 'geColor) deque
|
||||||
| `RightMin of ('geColor, 'substack, 'color) deque]
|
| `RightMin of ('geColor, 'substack, 'color) deque]
|
||||||
|
@ -153,12 +73,12 @@ module DequesColorsStack = struct
|
||||||
| `LeftOnly of ('color, [`Nil], empty) deque
|
| `LeftOnly of ('color, [`Nil], empty) deque
|
||||||
| `RightOnly of ( empty, [`Nil], 'color) deque]
|
| `RightOnly of ( empty, [`Nil], 'color) deque]
|
||||||
|
|
||||||
type 'a minTail = ('a yellow, 'a geYellow, 'a minTail) min
|
type 'a minTail = Deque1 of ('a yellow, 'a geYellow, 'a child minTail) min
|
||||||
type ('a, 'color, 'geColor) min' = ('color, 'geColor, 'a minTail) min
|
type 'a lastMinTail = Deque2 of ('a yellow, 'a geYellow, 'a child lastMinTail) lastMin
|
||||||
type ('a, 'color, 'geColor) lastMin' = ('color, 'geColor, 'a minTail) lastMin
|
type ('a, 'color, 'geColor) min' = ('color, 'geColor, 'a child minTail) min
|
||||||
|
type ('a, 'color, 'geColor) lastMin' = ('color, 'geColor, 'a child lastMinTail) lastMin
|
||||||
|
|
||||||
(** jacm-final.pdf p.9 (585) §4.1 media 60 290 368 60 *)
|
(** jacm-final.pdf p.9 (585) §4.1 media 60 290 368 60 *)
|
||||||
(* TODO: move the decision just around min and lastMin, and merge min' with lastMin' *)
|
|
||||||
type ('a, 'color, 'geColor, 'b_last) substack = 'result
|
type ('a, 'color, 'geColor, 'b_last) substack = 'result
|
||||||
constraint 'b_last = ( 'a, 'color, 'geColor) min'
|
constraint 'b_last = ( 'a, 'color, 'geColor) min'
|
||||||
* ('a, 'color, 'geColor) lastMin'
|
* ('a, 'color, 'geColor) lastMin'
|
||||||
|
@ -169,6 +89,9 @@ module DequesColorsStack = struct
|
||||||
type ('a, 'b_last) yellowSubstack = ('a, 'a yellow, 'a geYellow, 'b_last) substack
|
type ('a, 'b_last) yellowSubstack = ('a, 'a yellow, 'a geYellow, 'b_last) substack
|
||||||
type ('a, 'b_last) redSubstack = ('a, 'a red, 'a geRed, 'b_last) substack
|
type ('a, 'b_last) redSubstack = ('a, 'a red, 'a geRed, 'b_last) substack
|
||||||
|
|
||||||
|
(** jacm-final.pdf p.9 (585) §4.1 media 60 290 368 60 *)
|
||||||
|
(* In order to simplify the description of the types, we have separated the
|
||||||
|
outer stack from the substacks. *)
|
||||||
type 'a gStackLast = [ `GreenStackLast of ('a, 't * 'f * 't) greenSubstack * [`Null]]
|
type 'a gStackLast = [ `GreenStackLast of ('a, 't * 'f * 't) greenSubstack * [`Null]]
|
||||||
type 'a yStackLast = [ `YellowStackLast of ('a, 't * 'f * 't) yellowSubstack * [`Null]]
|
type 'a yStackLast = [ `YellowStackLast of ('a, 't * 'f * 't) yellowSubstack * [`Null]]
|
||||||
type 'a rStackLast = [ `RedStackLast of ('a, 't * 'f * 't) redSubstack * [`Null]]
|
type 'a rStackLast = [ `RedStackLast of ('a, 't * 'f * 't) redSubstack * [`Null]]
|
||||||
|
@ -193,7 +116,6 @@ module DequesColorsStack = struct
|
||||||
practice, these cases are already disjoint types, but performing their
|
practice, these cases are already disjoint types, but performing their
|
||||||
union is more readily done by defining a variant at this level. *)
|
union is more readily done by defining a variant at this level. *)
|
||||||
|
|
||||||
(** jacm-final.pdf p.9 (585) §4.1 media 60 290 368 60 *)
|
|
||||||
type 'a semiregular = ['a greenStack | 'a yellowGRStack | 'a redStack]
|
type 'a semiregular = ['a greenStack | 'a yellowGRStack | 'a redStack]
|
||||||
(** jacm-final.pdf p.9 (585) §4.1 media 60 338 368 24 *)
|
(** jacm-final.pdf p.9 (585) §4.1 media 60 338 368 24 *)
|
||||||
type 'a regular = ['a greenStack | 'a yellowGStack | 'a redStack]
|
type 'a regular = ['a greenStack | 'a yellowGStack | 'a redStack]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user