Skip to content

Commit 90cef6e

Browse files
only recursive defs left to implement
1 parent 785beeb commit 90cef6e

12 files changed

Lines changed: 235 additions & 66 deletions

File tree

dune-project

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
(maintainers "Thibaut Benjamin <thibaut.benjamin@gmail.com>"
99
"Chiara Sarti <cs2197@cam.ac.uk>")
1010
(license MIT)
11-
(using menhir 2.0)
11+
(using menhir 3.0)
1212
(cram enable)
1313
(using coq 0.9)
1414

examples/test.catt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
let idU (x : *) : Inv(id x) = can (id x {})
2+
3+
let compididU (x : *) : Inv(comp (id x) (id x)) =
4+
can ( (comp (id x) (id x)) { (idU x) , (idU x) })
5+
6+
let compinv (x : *) (y : *) (z : *)
7+
(f : x -> y) (g : y -> z)
8+
(e : Inv (f)) (e' : Inv (g)) =
9+
can ( (comp f g) { e , e' })
10+
11+
coh assoc (x(f)y(g)z(h)w) : comp (comp f g) h -> comp f (comp g h)
12+
coh assoc- (x(f)y(g)z(h)w) : comp f (comp g h) -> comp (comp f g) h
13+
14+
coind 2of6
15+
(x : *) (y : *) (z : *) (w : *)
16+
(f : x -> y) (g : y -> z) (h : z -> w)
17+
(e : Inv(comp f g)) (e' : Inv(comp g h)) =
18+
{ g ,
19+
comp (left (e)) f,
20+
comp h (right (e')) ,
21+
comp (assoc (left (e)) f g) (ε (e)) ,
22+
comp (assoc- g h (right (e'))) (η (e')) ,
23+
can (comp (assoc (left (e)) f g) (ε (e)) { can (assoc (left (e)) f g {}) , Iε (e) } ) ,
24+
can (
25+
comp (assoc- g h (right (e'))) (η (e')) { can (assoc- g h (right (e')) {}) , Iη (e') } )
26+
}

lib/dune

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
(menhir
2-
(modules parser))
2+
(modules parser)
3+
(explain "true"))
34

45
(ocamllex lexer)
56

lib/elaborate.ml

Lines changed: 94 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -41,25 +41,33 @@ module Constraints = struct
4141
(NotUnifiable (Unchecked.ty_to_string ty1, Unchecked.ty_to_string ty2))
4242

4343
and unify_tm cst tm1 tm2 =
44-
match (tm1, tm2) with
45-
| Meta_tm _, Meta_tm _ when tm1 = tm2 -> ()
46-
| Meta_tm _, _ | _, Meta_tm _ -> Queue.enqueue cst.tm (tm1, tm2)
47-
| Var v1, Var v2 when v1 = v2 -> ()
48-
| Coh (coh1, s1), Coh (coh2, s2) -> (
49-
try
50-
Coh.check_equal coh1 coh2;
51-
unify_sub_ps cst s1 s2
52-
with Invalid_argument _ ->
53-
raise (NotUnifiable (Coh.to_string coh1, Coh.to_string coh2)))
54-
| App (t1, s1), App (t2, s2) when t1 == t2 -> unify_sub cst s1 s2
55-
| App (t, s), ((App _ | Coh _ | Var _) as tm2)
56-
| ((Coh _ | Var _) as tm2), App (t, s) ->
57-
unify_tm cst (Unchecked.tm_apply_sub (Tm.develop t) s) tm2
58-
| Var _, Coh _ | Coh _, Var _ | Var _, Var _ ->
59-
raise
60-
(NotUnifiable (Unchecked.tm_to_string tm1, Unchecked.tm_to_string tm2))
61-
| _, _ ->
62-
Error.fatal "unification not implemented for invertibility structures"
44+
(* Io.debug "unfiying tm %s and %s" *)
45+
(* (Unchecked.tm_to_string tm1) *)
46+
(* (Unchecked.tm_to_string tm2); *)
47+
if tm1 = tm2 then ()
48+
else
49+
match (tm1, tm2) with
50+
| Meta_tm _, _ | _, Meta_tm _ -> Queue.enqueue cst.tm (tm1, tm2)
51+
| Var v1, Var v2 when v1 = v2 -> ()
52+
| Coh (coh1, s1), Coh (coh2, s2) -> (
53+
try
54+
Coh.check_equal coh1 coh2;
55+
unify_sub_ps cst s1 s2
56+
with Invalid_argument _ ->
57+
raise (NotUnifiable (Coh.to_string coh1, Coh.to_string coh2)))
58+
| App (t1, s1), App (t2, s2) when t1 == t2 -> unify_sub cst s1 s2
59+
| App (t, s), ((App _ | Coh _ | Var _) as tm2)
60+
| ((Coh _ | Var _) as tm2), App (t, s) ->
61+
unify_tm cst (Unchecked.tm_apply_sub (Tm.develop t) s) tm2
62+
| Var _, Coh _ | Coh _, Var _ | Var _, Var _ ->
63+
raise
64+
(NotUnifiable
65+
(Unchecked.tm_to_string tm1, Unchecked.tm_to_string tm2))
66+
| _, _ ->
67+
Error.fatal
68+
(Printf.sprintf "trying to unify %s and %s"
69+
(Unchecked.tm_to_string tm1)
70+
(Unchecked.tm_to_string tm2))
6371

6472
and unify_sub cst s1 s2 =
6573
match (s1, s2) with
@@ -111,6 +119,20 @@ module Constraints = struct
111119
List.map
112120
(fun (x, (t, e)) -> (x, (tm_replace_meta_tm (i, tm') t, e)))
113121
s )
122+
| Can (tm, tms) ->
123+
Can
124+
( tm_replace_meta_tm (i, tm') tm,
125+
List.map (tm_replace_meta_tm (i, tm')) tms )
126+
| IS (inv, u) -> IS (inv, tm_replace_meta_tm (i, tm') u)
127+
| Coind (t0, t1, t2, t3, t4, t5, t6) ->
128+
Coind
129+
( tm_replace_meta_tm (i, tm') t0,
130+
tm_replace_meta_tm (i, tm') t1,
131+
tm_replace_meta_tm (i, tm') t2,
132+
tm_replace_meta_tm (i, tm') t3,
133+
tm_replace_meta_tm (i, tm') t4,
134+
tm_replace_meta_tm (i, tm') t5,
135+
tm_replace_meta_tm (i, tm') t6 )
114136
| _ ->
115137
Error.fatal
116138
"resolution of meta_variables in invertibility\n\
@@ -194,8 +216,26 @@ module Constraints = struct
194216
aux c { uty = []; utm = [] }
195217
end
196218

219+
let inverse_ty ty =
220+
match ty with
221+
| Obj | Inv _ -> assert false
222+
| Arr (ty, u, v) -> Arr (ty, v, u)
223+
| Meta_ty _ -> Meta.new_ty ()
224+
225+
let lunit_ty tm linv =
226+
let y = Construct.tgt 1 tm in
227+
Construct.arr (Construct.comp linv tm) (Construct.id y)
228+
229+
let runit_ty tm rinv =
230+
let x = Construct.src 1 tm in
231+
Construct.arr (Construct.comp tm rinv) (Construct.id x)
232+
197233
module Constraints_typing = struct
198234
let rec tm ctx meta_ctx t cst =
235+
(* Io.debug "constraint typing term %s in ctx %s, meta_ctx %s" *)
236+
(* (Unchecked.tm_to_string t) *)
237+
(* (Unchecked.ctx_to_string ctx) *)
238+
(* (Unchecked.meta_ctx_to_string meta_ctx); *)
199239
Io.info ~v:5
200240
(lazy
201241
(Printf.sprintf "constraint typing term %s in ctx %s, meta_ctx %s"
@@ -222,6 +262,41 @@ module Constraints_typing = struct
222262
let ty = Ty.forget (Tm.typ t) in
223263
let s = sub ctx meta_ctx s tgt cst in
224264
(App (t, s), Unchecked.ty_apply_sub ty s)
265+
| Can (t, tms) ->
266+
let t, _ = tm ctx meta_ctx t cst in
267+
let tms = List.map (fun t -> fst (tm ctx meta_ctx t cst)) tms in
268+
(* ignore the constraints on tms : no elaboration *)
269+
(Can (t, tms), Inv t)
270+
| IS (inv, e) ->
271+
let e, te = tm ctx meta_ctx e cst in
272+
let u = match te with Inv u -> u | _ -> assert false in
273+
let u, tu = tm ctx meta_ctx u cst in
274+
let tui = inverse_ty tu in
275+
let ty =
276+
match inv with
277+
| LInv -> tui
278+
| RInv -> tui
279+
| Lunit -> lunit_ty (u, tu) (IS (LInv, e), tui)
280+
| Runit -> runit_ty (u, tu) (IS (RInv, e), tui)
281+
| Lwit -> Inv (IS (Lunit, e))
282+
| Rwit -> Inv (IS (Runit, e))
283+
in
284+
(IS (inv, e), ty)
285+
| Coind (t0, t1, t2, t3, t4, t5, t6) ->
286+
let t0, ty0 = tm ctx meta_ctx t0 cst in
287+
let t1, ty1 = tm ctx meta_ctx t1 cst in
288+
let t2, ty2 = tm ctx meta_ctx t2 cst in
289+
let t3, ty3 = tm ctx meta_ctx t3 cst in
290+
let t4, ty4 = tm ctx meta_ctx t4 cst in
291+
let t5, ty5 = tm ctx meta_ctx t5 cst in
292+
let t6, ty6 = tm ctx meta_ctx t6 cst in
293+
Constraints.unify_ty cst (inverse_ty ty0) ty1;
294+
Constraints.unify_ty cst (inverse_ty ty0) ty2;
295+
Constraints.unify_ty cst (lunit_ty (t0, ty0) (t1, ty1)) ty3;
296+
Constraints.unify_ty cst (runit_ty (t0, ty0) (t2, ty2)) ty4;
297+
Constraints.unify_ty cst (Inv t3) ty5;
298+
Constraints.unify_ty cst (Inv t4) ty6;
299+
(Coind (t0, t1, t2, t3, t4, t5, t6), Inv t0)
225300
| _ -> Error.fatal "invertibility structures in constraint typing"
226301

227302
and sub src meta_ctx s tgt cst =

lib/environment.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ let add_let v c ?ty t =
4141
let pp_data = (Var.to_string v, 0, []) in
4242
let kc = Kernel.Ctx.check c in
4343
let tm = Kernel.check_term kc ?ty ~name:pp_data t in
44-
let ty = Kernel.(Ty.forget (Tm.typ tm)) in
44+
let ty = Kernel.Tm.typ tm in
45+
let dim_output = Kernel.Ty.dim ty in
46+
let ty = Kernel.Ty.forget ty in
4547
let dim_input = Unchecked.dim_ctx c in
46-
let dim_output = Unchecked.dim_ty ty in
4748
Io.info ~v:4
4849
(lazy
4950
(Printf.sprintf "term %s of type %s added to environment"

lib/kernel.ml

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ module rec Sub : sig
2020
val free_vars : t -> Var.t list
2121
val src : t -> Ctx.t
2222
val tgt : t -> Ctx.t
23+
val args_of_dim : int -> t -> Tm.t list
2324
end = struct
2425
type t = {
2526
list : Tm.t list;
@@ -81,6 +82,16 @@ end = struct
8182
sub
8283

8384
let forget s = s.unchecked
85+
86+
let args_of_dim n s =
87+
let rec provide s tgt =
88+
match (s, tgt) with
89+
| [], [] -> []
90+
| tm :: s, (_, ty) :: tgt when Ty.dim ty == n -> tm :: provide s tgt
91+
| _ :: s, _ :: tgt -> provide s tgt
92+
| _, _ -> assert false
93+
in
94+
provide s.list (Ctx.value s.tgt)
8495
end
8596

8697
(** A context, associating a type to each context variable. *)
@@ -326,6 +337,7 @@ and Ty : sig
326337
val ctx : t -> Ctx.t
327338
val dim : t -> int
328339
val base_inv : t -> Tm.t
340+
val inv : Tm.t -> Ty.t
329341
end = struct
330342
open Unchecked (Coh) (Tm)
331343
module Unchecked = Make (Coh) (Tm)
@@ -407,6 +419,14 @@ end = struct
407419
let forget t = t.unchecked
408420
let to_string ty = Unchecked.ty_to_string (forget ty)
409421

422+
let inv t =
423+
match (Tm.typ t).e with
424+
| Obj | Inv _ -> assert false
425+
| Arr (_, _, _) ->
426+
let e = Inv t in
427+
let c = (Tm.typ t).c in
428+
{ c; e; unchecked = Inv (Tm.forget t) }
429+
410430
(** Test for equality. *)
411431
let check_equal ty1 ty2 =
412432
Ctx.check_equal ty1.c ty2.c;
@@ -432,7 +452,7 @@ end = struct
432452
match t.e with
433453
| Obj -> 0
434454
| Arr (a, _, _) -> 1 + dim a
435-
| Inv _ -> raise IsInv
455+
| Inv u -> dim (Tm.typ u)
436456
end
437457

438458
(** Operations on terms. *)
@@ -484,6 +504,7 @@ end = struct
484504
| Coh of Coh.t * Sub.t
485505
| App of Tm.t * Sub.t
486506
| IS of inv * Tm.t
507+
| Can of Tm.t * Tm.t list
487508
| Coind of Tm.t * Tm.t * Tm.t * Tm.t * Tm.t * Tm.t * Tm.t
488509
| Rec of Tm.t * Tm.t * Tm.t * Tm.t * Tm.t * Tm.t * Tm.t
489510

@@ -511,7 +532,7 @@ end = struct
511532
| Var x -> x :: fvty
512533
| Coh (_, sub) | App (_, sub) -> Sub.free_vars sub
513534
| IS (_, t) -> free_vars t
514-
(* | Can (t, _) -> free_vars t *)
535+
| Can (t, _) -> free_vars t
515536
| Coind (t, _, _, _, _, _, _) -> free_vars t
516537
| Rec (t, _, _, _, _, _, _) -> free_vars t
517538

@@ -533,7 +554,16 @@ end = struct
533554
let ty = Constr.arr (Constr.comp t rinv) (Constr.id x) in
534555
Ty.check c ty
535556

536-
let rec check c ?ty ?name t =
557+
let rec args_max_coh c tm =
558+
let tm = Tm.develop tm in
559+
let tm = check c tm in
560+
match tm.e with
561+
| Var _ | App _ | Coind _ | Rec _ | Can _ | IS _ -> assert false
562+
| Coh (c, sub) ->
563+
let n = Coh.dim c in
564+
Sub.args_of_dim n sub
565+
566+
and check c ?ty ?name t =
537567
Io.info ~v:5
538568
(lazy
539569
(Printf.sprintf "building\n kernel term %s in context %s"
@@ -573,17 +603,34 @@ end = struct
573603
let linv = check c (IS (LInv, tm)) in
574604
lunit_ty c base_inv linv
575605
| Runit ->
576-
let rinv = check c (IS (LInv, tm)) in
606+
let rinv = check c (IS (RInv, tm)) in
577607
runit_ty c base_inv rinv
578608
| Lwit -> Ty.check c (Inv (IS (Lunit, tm)))
579609
| Rwit -> Ty.check c (Inv (IS (Runit, tm)))
580610
in
581611
let tm = { ty; e; unchecked = t; developped = Some t; name } in
582612
Hashtbl.add tbl (c, t) tm;
583613
tm
584-
| Can (_, _) ->
585-
Error.fatal
586-
"canonical invertibility structures not yet implemented"
614+
| Can (tm, tms) ->
615+
let tm = check c tm in
616+
let args = args_max_coh c tm in
617+
let rec check_next args invs =
618+
match (args, invs) with
619+
| t :: args, e :: invs ->
620+
let e = Tm.check c ~ty:(Ty.inv t) e in
621+
let invs = check_next args invs in
622+
e :: invs
623+
| [], [] -> []
624+
| _ ->
625+
Error.fatal
626+
"wrong number of arguments in canonical structure"
627+
in
628+
let tms = check_next args tms in
629+
let e = Can (tm, tms) in
630+
let ty = Ty.inv tm in
631+
let tm = { ty; e; unchecked = t; developped = Some t; name } in
632+
Hashtbl.add tbl (c, t) tm;
633+
tm
587634
| Coind (t0, t1, t2, t3, t4, t5, t6) ->
588635
let t0_checked = check c t0 in
589636
let _, x, y = Ty.retrieve_arrow t0_checked.ty in
@@ -593,7 +640,7 @@ end = struct
593640
check c ~ty:(lunit_ty c t0_checked t1_checked) t3
594641
in
595642
let t4_checked =
596-
check c ~ty:(runit_ty c t0_checked t1_checked) t4
643+
check c ~ty:(runit_ty c t0_checked t2_checked) t4
597644
in
598645
let t5_checked = check c ~ty:(Ty.check c (Inv t3)) t5 in
599646
let t6_checked = check c ~ty:(Ty.check c (Inv t4)) t6 in

lib/kernel.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ and Ty : sig
5353
type t
5454

5555
val forget : t -> Unchecked_types(Coh)(Tm).ty
56+
val dim : t -> int
5657
end
5758

5859
and Tm : sig

lib/lexer.mll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ rule token = parse
1616
| "can" { CAN }
1717
| "coind" { COIND }
1818
| "rec" { REC }
19+
| "," { COMMA }
1920
| "check" { CHECK }
2021
| "let" { LET }
2122
| "in" { IN }

lib/parser.mly

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
%token COH OBJ MOR WILD IGNORE
3636
%token INVTY LEFT RIGHT LUNIT RUNIT LWITNESS RWITNESS CAN COIND REC
37-
%token LPAR RPAR LBRA RBRA LCUR RCUR COL BANG OP AT
37+
%token LPAR RPAR LBRA RBRA LCUR RCUR COL BANG OP AT COMMA
3838
%token <string> BUILTIN
3939
%token <int*int*int> CONECOMP
4040
%token <int*int*int> CYLCOMP
@@ -76,8 +76,8 @@ cmd:
7676
| SET IDENT EQUAL IDENT { Set ($2,$4) }
7777
| SET IDENT EQUAL INT { Set ($2,$4) }
7878
| DECLARE IDENT EQUAL builtin { Decl_builtin (Var.make_var $2,$4) }
79-
| COIND IDENT args_or_ps EQUAL tmexpr tmexpr tmexpr tmexpr tmexpr tmexpr tmexpr { CoindDef (Var.make_var $2, $3, $5, $6, $7, $8, $9, $10, $11) }
80-
| REC IDENT args_or_ps EQUAL tmexpr tmexpr tmexpr tmexpr tmexpr tmexpr tmexpr { RecDef (Var.make_var $2, $3, $5, $6, $7, $8, $9, $10, $11) }
79+
| COIND IDENT args_or_ps EQUAL LCUR tmexpr COMMA tmexpr COMMA tmexpr COMMA tmexpr COMMA tmexpr COMMA tmexpr COMMA tmexpr RCUR { CoindDef (Var.make_var $2, $3, $6, $8, $10, $12, $14, $16, $18) }
80+
| REC IDENT args_or_ps EQUAL LCUR tmexpr COMMA tmexpr COMMA tmexpr COMMA tmexpr COMMA tmexpr COMMA tmexpr COMMA tmexpr RCUR { RecDef (Var.make_var $2, $3, $6, $8, $10, $12, $14, $16, $18) }
8181

8282
args_of_same_ty :
8383
| IDENT COL tyexpr { [Var.make_var $1, $3], $3 }
@@ -132,14 +132,17 @@ simple_tmexpr:
132132
| INV LPAR tmexpr RPAR { Inverse $3 }
133133
| UNIT LPAR tmexpr RPAR { Unit $3 }
134134
| invertibility_destructor LPAR tmexpr RPAR { ISR($1, $3) }
135-
| CAN LPAR tmexpr LBRA tmexpr_list RBRA RPAR { CanR($3, $5) }
135+
| CAN LPAR tmexpr LCUR tmexpr_list RCUR RPAR { CanR($3, $5) }
136136
| IDENT { VarR (Var.make_var $1) }
137137
| builtin_tm { $1 }
138138

139-
tmexpr_list:
140-
| tmexpr tmexpr_list { $1::$2 }
141-
| { [] }
139+
nonempty_tmexpr_list:
140+
| tmexpr_list COMMA tmexpr { $3::$1 }
141+
| tmexpr { [ $1 ] }
142142

143+
tmexpr_list :
144+
| nonempty_tmexpr_list { $1 }
145+
| { [] }
143146

144147
functed_tmexpr:
145148
| LBRA maybe_functed_tmexpr RBRA { let t,n = $2 in t,n+1 }

0 commit comments

Comments
 (0)