Skip to content

Commit c594806

Browse files
authored
feat: dimension inequalities (#9)
* feat(Graph)!: replace disjoint sets with graphs * feat: implement inequalities * docs(Theory): update the doc * fix(Theory): handle dim0 and dim1 correctly * test(Graph): add testing for Graph * fix: really handle dim0 and dim1 * fix(Builder): fix another bug
1 parent 5e50a0d commit c594806

File tree

14 files changed

+260
-206
lines changed

14 files changed

+260
-206
lines changed

kado.opam

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ depends: [
1414
"dune" {>= "2.0"}
1515
"ocaml" {>= "4.10"}
1616
"bwd" {>= "1.0"}
17+
"qcheck-core" {>= "0.18" & with-test}
1718
"odoc" {with-doc}
1819
]
1920
build: [

src/Builder.ml

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ struct
1616
type dim
1717
type cof
1818
val cof : (dim, cof) Syntax.endo -> cof
19+
val le : dim -> dim -> cof
1920
val eq : dim -> dim -> cof
2021
val eq0 : dim -> cof
2122
val eq1 : dim -> cof
@@ -31,32 +32,15 @@ struct
3132
struct
3233
include P
3334

34-
let eq x y = cof @@
35-
let (=) = equal_dim in
36-
if x = y then
37-
Syntax.Endo.top
38-
else if (x = dim0 && y = dim1) || (x = dim1 && y = dim0) then
39-
Syntax.Endo.bot
40-
else
41-
Syntax.Endo.eq x y
42-
43-
let eq0 x = cof @@
44-
let (=) = equal_dim in
45-
if x = dim0 then
46-
Syntax.Endo.top
47-
else if x = dim1 then
48-
Syntax.Endo.bot
49-
else
50-
Syntax.Endo.eq x dim0
35+
let (=) = equal_dim
5136

52-
let eq1 x = cof @@
53-
let (=) = equal_dim in
54-
if x = dim1 then
37+
let le x y = cof @@
38+
if dim0 = x || x = y || y = dim1 then
5539
Syntax.Endo.top
56-
else if x = dim0 then
40+
else if x = dim1 && y = dim0 then
5741
Syntax.Endo.bot
5842
else
59-
Syntax.Endo.eq x dim1
43+
Syntax.Endo.le x y
6044

6145
let bot = cof Syntax.Endo.bot
6246
let top = cof Syntax.Endo.top
@@ -81,17 +65,24 @@ struct
8165
| [phi] -> phi
8266
| l -> cof @@ Syntax.Endo.meet l
8367

68+
let eq x y = meet [le x y; le y x]
69+
70+
let eq0 x = eq x dim0
71+
72+
let eq1 x = eq x dim1
73+
8474
let boundary r = join [eq0 r; eq1 r]
8575

8676
let forall (sym, cof) =
8777
let rec go cof =
8878
match uncof cof with
8979
| None -> cof
90-
| Some Eq (x, y) ->
80+
| Some Le (x, y) ->
9181
begin
9282
match equal_dim x sym, equal_dim y sym with
9383
| true, true -> top
94-
| true, false | false, true -> bot
84+
| true, false -> if y = dim1 then top else bot
85+
| false, true -> if x = dim0 then top else bot
9586
| _ -> eq x y
9687
end
9788
| Some Meet phis -> meet @@ List.map go phis

src/Builder.mli

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ sig
3939
(** The embedding of cofibrations to [cof]. *)
4040
val cof : (dim, cof) Syntax.endo -> cof
4141

42-
(** Smarter version of {!val:Syntax.Endo.eq} that checks equality. *)
42+
(** Smarter version of {!val:Syntax.Endo.le} that checks equality. *)
43+
val le : dim -> dim -> cof
44+
45+
(** Smarter version of [meet [le x y; le y x]]. *)
4346
val eq : dim -> dim -> cof
4447

4548
(** [eq0 r] is [eq r dim0]. *)
@@ -71,7 +74,10 @@ sig
7174
val boundary : dim -> cof
7275

7376
(** [forall (r, cof)] computes [forall r. cof], using the syntactic quantifier elimination
74-
and potentially other simplification procedures used in {!val:eq}, {!val:join}, and {!val:meet}. *)
77+
and potentially other simplification procedures used in {!val:eq}, {!val:join}, and {!val:meet}.
78+
79+
Note: [r] cannot be [dim0] or [dim1].
80+
*)
7581
val forall : dim * cof -> cof
7682
end
7783

src/DisjointSet.ml

Lines changed: 0 additions & 93 deletions
This file was deleted.

src/Graph.ml

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
module type Vertex =
2+
sig
3+
type t
4+
val compare : t -> t -> int
5+
6+
val initial : t (* if you pretent the graph is a category *)
7+
val terminal : t
8+
end
9+
10+
module type S =
11+
sig
12+
type key
13+
type t
14+
15+
val empty : t
16+
val test : key -> key -> t -> bool
17+
val union : key -> key -> t -> t
18+
val test_and_union : key -> key -> t -> bool * t
19+
20+
val merge : t -> t -> t
21+
end
22+
23+
module Make (V : Vertex) : S with type key = V.t =
24+
struct
25+
module M = Map.Make (V)
26+
module S = Set.Make (V)
27+
28+
type vertex = V.t
29+
type key = vertex
30+
31+
let (=) v1 v2 = V.compare v1 v2 = 0
32+
33+
type t =
34+
{ reachable : S.t M.t;
35+
reduced : V.t list M.t }
36+
37+
let empty : t =
38+
{ reachable = M.of_seq @@ List.to_seq
39+
[V.initial, S.of_list [V.initial; V.terminal];
40+
V.terminal, S.singleton V.terminal];
41+
reduced = M.of_seq @@ List.to_seq
42+
[V.initial, [V.terminal];
43+
V.terminal, []] }
44+
45+
let mem_vertex (v : vertex) (g : t) : bool = M.mem v g.reachable
46+
47+
let touch_vertex (v : vertex) (g : t) : t =
48+
if mem_vertex v g then g else
49+
{ reachable =
50+
M.add v (S.add v (M.find V.terminal g.reachable)) @@
51+
M.map (fun s -> if S.mem V.initial s then S.add v s else s) @@
52+
g.reachable;
53+
reduced =
54+
M.update V.initial (fun l -> Some (v :: Option.get l)) @@
55+
M.update v (function None -> Some [V.terminal] | _ as l -> l) @@
56+
g.reduced
57+
}
58+
59+
let raw_test (u : vertex) (v : vertex) (g : t) =
60+
S.mem v (M.find u g.reachable)
61+
62+
let test (u : vertex) (v : vertex) (g : t) =
63+
match mem_vertex u g, mem_vertex v g with
64+
| true, true -> raw_test u v g
65+
| true, false -> raw_test u V.initial g
66+
| false, true -> raw_test V.terminal v g
67+
| false, false -> u = v || raw_test V.terminal V.initial g
68+
69+
let union (u : vertex) (v : vertex) (g : t) =
70+
if test u v g then g else
71+
let g = touch_vertex v @@ touch_vertex u g in
72+
let rec meld i rx =
73+
let f rx j = if S.mem j rx then rx else meld j (S.add j rx) in
74+
List.fold_left f rx (M.find i g.reduced)
75+
in
76+
{ reduced = M.update u (fun l -> Some (v :: Option.get l)) g.reduced;
77+
reachable =
78+
g.reachable
79+
|> M.map @@ fun rx ->
80+
if S.mem u rx && not (S.mem v rx) then
81+
meld v @@ S.add v rx
82+
else
83+
rx }
84+
85+
let test_and_union (u : vertex) (v : vertex) (g : t) =
86+
test u v g, union u v g
87+
88+
let merge (g1 : t) (g2 : t) =
89+
M.fold (fun u -> List.fold_right (union u)) g1.reduced g2
90+
end
Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
module type Vertex =
2+
sig
3+
type t
4+
val compare : t -> t -> int
5+
6+
val initial : t
7+
val terminal : t
8+
end
9+
110
module type S =
211
sig
312
type key
@@ -9,10 +18,6 @@ sig
918
val test_and_union : key -> key -> t -> bool * t
1019

1120
val merge : t -> t -> t
12-
13-
type finger
14-
val finger : key -> t -> finger
15-
val test_finger : key -> finger -> bool
1621
end
1722

18-
module Make (O : Map.OrderedType) : S with type key = O.t
23+
module Make (V : Vertex) : S with type key = V.t

src/Kado.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ module Syntax = Syntax
33
module Builder = Builder
44

55
module Theory = Theory
6+
7+
module Graph = Graph

src/Kado.mli

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,7 @@ module Builder : module type of Builder
1212

1313
(** The {!module:Theory} module implements decision procedures for sequents relative to a theory over the interval, stated in the language of cofibrations. *)
1414
module Theory : module type of Theory
15+
16+
(**/**)
17+
18+
module Graph : module type of Graph

src/Syntax.ml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
type ('r, 'a) endo =
2-
| Eq of 'r * 'r
2+
| Le of 'r * 'r
33
| Join of 'a list
44
| Meet of 'a list
55

@@ -10,7 +10,7 @@ type ('r, 'v) free =
1010
module Endo =
1111
struct
1212
type ('r, 'a) t = ('r, 'a) endo =
13-
| Eq of 'r * 'r
13+
| Le of 'r * 'r
1414
| Join of 'a list
1515
| Meet of 'a list
1616

@@ -20,18 +20,18 @@ struct
2020
let bot = join []
2121
let top = meet []
2222

23-
let eq x y = Eq (x, y)
23+
let le x y = Le (x, y)
2424

2525
let map f =
2626
function
27-
| Eq _ as phi -> phi
27+
| Le _ as phi -> phi
2828
| Join l -> Join (List.map f l)
2929
| Meet l -> Meet (List.map f l)
3030

3131
let dump dump_r dump_a fmt =
3232
function
33-
| Eq (r1, r2) ->
34-
Format.fprintf fmt "@[<hv 1>eq[@,@[%a@];@,@[%a@]]@]" dump_r r1 dump_r r2
33+
| Le (r1, r2) ->
34+
Format.fprintf fmt "@[<hv 1>le[@,@[%a@];@,@[%a@]]@]" dump_r r1 dump_r r2
3535
| Join l ->
3636
Format.fprintf fmt "@[<hv 1>join[@,%a]@]"
3737
(Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt ";@,") dump_a) l
@@ -43,7 +43,7 @@ end
4343
module Free =
4444
struct
4545
type nonrec ('r, 'a) endo = ('r, 'a) endo =
46-
| Eq of 'r * 'r
46+
| Le of 'r * 'r
4747
| Join of 'a list
4848
| Meet of 'a list
4949

@@ -54,7 +54,7 @@ struct
5454
let var v = Var v
5555
let cof c = Cof c
5656

57-
let eq x y = cof @@ Endo.eq x y
57+
let le x y = cof @@ Endo.le x y
5858
let join phis = cof @@ Endo.join phis
5959
let meet phis = cof @@ Endo.meet phis
6060
let bot = cof Endo.bot

0 commit comments

Comments
 (0)