-
Notifications
You must be signed in to change notification settings - Fork 51
/
coq_elpi_arg_HOAS.ml
1161 lines (1038 loc) · 51.3 KB
/
coq_elpi_arg_HOAS.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
(* coq-elpi: Coq terms as the object language of elpi *)
(* license: GNU Lesser General Public License Version 2.1 or later *)
(* ------------------------------------------------------------------------- *)
module API = Elpi.API
module E = API.RawData
module CD = API.RawOpaqueData
open Coq_elpi_utils
open Coq_elpi_HOAS
open Names
type phase = Interp | Synterp | Both
let push_name x = function
| Names.Name.Name id ->
let decl = Context.Named.Declaration.LocalAssum (Context.make_annot id Sorts.Relevant, Constr.mkProp) in
{ x with Genintern.genv = Environ.push_named decl x.Genintern.genv }
| _ -> x
let push_gdecl (name,_,_,_,_) x = push_name x name
let push_glob_ctx glob_ctx x =
List.fold_right push_gdecl glob_ctx x
let push_inductive_in_intern_env intern_env name params arity user_impls =
let env = Global.env () in
let sigma = Evd.from_env env in
let sigma, ty = Pretyping.understand_tcc env sigma ~expected_type:Pretyping.IsType (Coq_elpi_utils.mk_gforall arity params) in
ty, Constrintern.compute_internalization_env env sigma ~impls:intern_env
Constrintern.Inductive [name] [ty] [user_impls]
let intern_tactic_constr = Ltac_plugin.Tacintern.intern_constr
let intern_global_constr { Ltac_plugin.Tacintern.genv = env } ~intern_env t =
let sigma = Evd.from_env env in
Constrintern.intern_gen Pretyping.WithoutTypeConstraint env sigma ~impls:intern_env ~pattern_mode:false ~ltacvars:Constrintern.empty_ltac_sign t
let intern_global_constr_ty { Ltac_plugin.Tacintern.genv = env } ~intern_env ?(expty=Pretyping.IsType) t =
let sigma = Evd.from_env env in
Constrintern.intern_gen expty env sigma ~impls:intern_env ~pattern_mode:false ~ltacvars:Constrintern.empty_ltac_sign t
let intern_global_context { Ltac_plugin.Tacintern.genv = env } ~intern_env ctx =
Constrintern.intern_context env ~bound_univs:UnivNames.empty_binders intern_env ctx
let intern_one h =
let open Constrexpr in
match h with
| CLocalAssum(nl,_,Default bk,_) -> nl |> List.map (fun n -> n.CAst.v,None,bk,None,mkGHole)
| CLocalAssum(nl,_,Generalized(bk,_),_) -> nl |> List.map (fun n -> n.CAst.v,None,bk,None,mkGHole)
| CLocalDef (n,_,_,None) -> [n.CAst.v,None,Glob_term.Explicit,None,mkGHole]
| CLocalDef (n,_,_,Some _) -> [n.CAst.v,None,Glob_term.Explicit,Some mkGHole,mkGHole]
| CLocalPattern _ -> nYI "irrefutable pattern in synterp"
let drop_relevance (a,_,c,d,e) = (a,c,d,e)
let intern_global_context_synterp (ctx : Constrexpr.local_binder_expr list) : Glob_term.glob_decl list =
CList.concat_map intern_one ctx |> List.rev
module Cmd = struct
type raw_term = Constrexpr.constr_expr
type glob_term = Genintern.glob_constr_and_expr
type top_term =
Ltac_plugin.Tacinterp.interp_sign * Genintern.glob_constr_and_expr
type raw_record_decl = Vernacentries.Preprocessed_Mind_decl.record
type glob_record_decl = Genintern.glob_sign * raw_record_decl
type top_record_decl = Geninterp.interp_sign * glob_record_decl
type raw_indt_decl = Vernacentries.Preprocessed_Mind_decl.inductive
type glob_indt_decl = Genintern.glob_sign * raw_indt_decl
type top_indt_decl = Geninterp.interp_sign * glob_indt_decl
type univpoly = Mono | Poly | CumulPoly
type raw_record_decl_elpi = {
name : qualified_name;
parameters : Constrexpr.local_binder_expr list;
sort : Constrexpr.sort_expr option;
constructor : Names.Id.t option;
fields : (Vernacexpr.local_decl_expr * Vernacexpr.record_field_attr) list;
univpoly : univpoly;
}
type glob_record_decl_elpi = {
name : string list * Names.Id.t;
constructorname : Names.Id.t option;
params : Glob_term.glob_decl list;
arity : Glob_term.glob_constr;
fields : (Glob_term.glob_constr * Coq_elpi_HOAS.record_field_spec) list;
univpoly : univpoly;
}
let pr_raw_record_decl _ _ _ = Pp.str "TODO: pr_raw_record_decl"
let pr_glob_record_decl _ _ _ = Pp.str "TODO: pr_glob_record_decl"
let pr_top_record_decl _ _ _ = Pp.str "TODO: pr_top_record_decl"
type raw_indt_decl_elpi = {
finiteness : Declarations.recursivity_kind;
name : qualified_name;
parameters : Constrexpr.local_binder_expr list;
non_uniform_parameters : Constrexpr.local_binder_expr list option;
arity : Constrexpr.constr_expr option;
constructors : (Names.lident * Constrexpr.constr_expr) list;
univpoly : univpoly;
}
type glob_indt_decl_elpi = {
finiteness : Declarations.recursivity_kind;
name : string list * Names.Id.t;
arity : Glob_term.glob_constr;
params : Glob_term.glob_decl list;
nuparams : Glob_term.glob_decl list;
nuparams_given : bool;
constructors : (Names.Id.t * Glob_term.glob_constr) list;
univpoly : univpoly;
}
let pr_raw_indt_decl _ _ _ = Pp.str "TODO: pr_raw_indt_decl"
let pr_glob_indt_decl _ _ _ = Pp.str "TODO: pr_glob_indt_decl"
let pr_top_indt_decl _ _ _ = Pp.str "TODO: pr_top_indt_decl"
type raw_constant_decl = {
name : qualified_name;
atts : Attributes.vernac_flags;
udecl : Constrexpr.universe_decl_expr option;
typ : Constrexpr.local_binder_expr list * Constrexpr.constr_expr option;
body : Constrexpr.constr_expr option;
red : Genredexpr.raw_red_expr option;
}
type glob_constant_decl_elpi = {
name : string list * Names.Id.t;
udecl : universe_decl_option;
params : Glob_term.glob_decl list;
typ : Glob_term.glob_constr;
body : Glob_term.glob_constr option;
}
type glob_constant_decl = Genintern.glob_sign * raw_constant_decl
type top_constant_decl = Geninterp.interp_sign * glob_constant_decl
let pr_raw_constant_decl _ _ _ = Pp.str "TODO: pr_raw_constant_decl"
let pr_glob_constant_decl _ _ _ = Pp.str "TODO: pr_glob_constant_decl"
let pr_top_constant_decl _ _ _ = Pp.str "TODO: pr_top_constant_decl"
type raw_context_decl = Constrexpr.local_binder_expr list
type glob_context_decl = Genintern.glob_sign * raw_context_decl
type top_context_decl = Geninterp.interp_sign * glob_context_decl
let pr_raw_context_decl _ _ _ = Pp.str "TODO: pr_raw_context_decl"
let pr_glob_context_decl _ _ _ = Pp.str "TODO: pr_glob_context_decl"
let pr_top_context_decl _ _ _ = Pp.str "TODO: pr_top_context_decl"
type ('a,'b,'c,'d,'e) t =
| Int : int -> ('a,'b,'c,'d,'e) t
| String : string -> ('a,'b,'c,'d,'e) t
| Term : 'a -> ('a,'b,'c,'d,'e) t
| RecordDecl : 'b -> ('a,'b,'c,'d,'e) t
| IndtDecl : 'c -> ('a,'b,'c,'d,'e) t
| ConstantDecl : 'd -> ('a,'b,'c,'d,'e) t
| Context : 'e -> ('a,'b,'c,'d,'e) t
type raw = (raw_term, raw_record_decl, raw_indt_decl, raw_constant_decl, raw_context_decl) t
type glob = (glob_term, glob_record_decl, glob_indt_decl, glob_constant_decl, glob_context_decl) t
type top = (top_term, top_record_decl, top_indt_decl, top_constant_decl, top_context_decl) t
let pr_arg f g h i j x = match x with
| Int n -> Pp.int n
| String s -> Pp.qstring s
| Term s -> f s
| RecordDecl s -> g s
| IndtDecl s -> h s
| ConstantDecl s -> i s
| Context c -> j c
let pp_raw env sigma : raw -> Pp.t =
pr_arg
(Ppconstr.pr_constr_expr env sigma)
(pr_raw_record_decl env sigma)
(pr_raw_indt_decl env sigma)
(pr_raw_constant_decl env sigma)
(pr_raw_context_decl env sigma)
let pr_glob_constr_and_expr env sigma = function
| (_, Some c) ->
Ppconstr.pr_constr_expr env sigma c
| (c, None) ->
Printer.pr_glob_constr_env env sigma c
let pp_glob env sigma : glob -> Pp.t =
pr_arg
(pr_glob_constr_and_expr env sigma)
(pr_glob_record_decl env sigma)
(pr_glob_indt_decl env sigma)
(pr_glob_constant_decl env sigma)
(pr_glob_context_decl env sigma)
let pp_top env sigma : top -> Pp.t =
pr_arg
(fun (_,x) -> pr_glob_constr_and_expr env sigma x)
(pr_top_record_decl env sigma)
(pr_top_indt_decl env sigma)
(pr_top_constant_decl env sigma)
(pr_top_context_decl env sigma)
let sep_last_qualid = function
| [] -> "_", []
| l -> CList.sep_last l
let univpoly_of ~poly ~cumulative =
match poly, cumulative with
| true, true -> CumulPoly
| true, false -> Poly
| false, _ -> Mono
[%%if coq = "8.20"]
let of_coq_inductive_definition id =
let open Vernacentries.Preprocessed_Mind_decl in
let { flags; typing_flags; private_ind; uniform; inductives } = id in
if List.length inductives != 1 then nYI "mutual inductives";
let inductive = List.hd inductives in
let (((name),(parameters,non_uniform_parameters),arity,constructors),notations) = inductive in
if notations != [] then CErrors.user_err Pp.(str "notations not supported");
let name = [Names.Id.to_string name.CAst.v] in
let constructors =
List.map (function (Vernacexpr.(_,NoCoercion,NoInstance),c) -> c
| _ -> CErrors.user_err Pp.(str "coercion and instance flags not supported"))
constructors in
let { template; udecl; cumulative; poly; finite } = flags in
if template <> None then nYI "raw template polymorphic inductives";
if udecl <> None then nYI "raw universe polymorphic inductives with universe declaration";
{
finiteness = finite;
name;
parameters;
non_uniform_parameters;
arity;
constructors;
univpoly = univpoly_of ~poly ~cumulative
}
[%%else]
let of_coq_inductive_definition id =
let open Vernacentries.Preprocessed_Mind_decl in
let { flags; udecl; typing_flags; private_ind; uniform; inductives } = id in
if List.length inductives != 1 then nYI "mutual inductives";
let inductive = List.hd inductives in
let (((name),(parameters,non_uniform_parameters),arity,constructors),notations) = inductive in
if notations != [] then CErrors.user_err Pp.(str "notations not supported");
let name = [Names.Id.to_string name.CAst.v] in
let constructors =
List.map (function (Vernacexpr.(_,NoCoercion,NoInstance),c) -> c
| _ -> CErrors.user_err Pp.(str "coercion and instance flags not supported"))
constructors in
let { ComInductive.template; cumulative; poly; finite } = flags in
if template <> None then nYI "raw template polymorphic inductives";
if udecl <> None then nYI "raw universe polymorphic inductives with universe declaration";
{
finiteness = finite;
name;
parameters;
non_uniform_parameters;
arity;
constructors;
univpoly = univpoly_of ~poly ~cumulative
}
[%%endif]
[%%if coq = "8.20"]
let of_coq_record_definition id =
let open Vernacentries.Preprocessed_Mind_decl in
let { flags; primitive_proj; kind; records; } : record = id in
if List.length records != 1 then nYI "mutual inductives";
let open Record.Ast in
let { name; is_coercion; binders : Constrexpr.local_binder_expr list; cfs; idbuild; sort; default_inhabitant_id : Names.Id.t option; } = List.hd records in
if is_coercion = Vernacexpr.AddCoercion then CErrors.user_err Pp.(str "coercion flag not supported");
let name = [Names.Id.to_string name.CAst.v] in
let sort = sort |> Option.map (fun sort ->
match sort.CAst.v with
| Constrexpr.CSort s -> s
| _ -> CErrors.user_err ?loc:sort.CAst.loc Pp.(str "only explicits sorts are supported")) in
let { template; udecl; cumulative; poly; finite } = flags in
if template <> None then nYI "raw template polymorphic inductives";
if udecl <> None then nYI "raw universe polymorphic inductives with universe declaration";
{
name;
parameters = binders;
sort;
constructor = Some idbuild;
fields = cfs;
univpoly = univpoly_of ~poly ~cumulative
}
[%%else]
let of_coq_record_definition id =
let open Vernacentries.Preprocessed_Mind_decl in
let { flags; udecl; primitive_proj; kind; records; } : record = id in
if List.length records != 1 then nYI "mutual inductives";
let open Record.Ast in
let { name; is_coercion; binders : Constrexpr.local_binder_expr list; cfs; idbuild; sort; default_inhabitant_id : Names.Id.t option; } = List.hd records in
if is_coercion = Vernacexpr.AddCoercion then CErrors.user_err Pp.(str "coercion flag not supported");
let name = [Names.Id.to_string name.CAst.v] in
let sort = sort |> Option.map (fun sort ->
match sort.CAst.v with
| Constrexpr.CSort s -> s
| _ -> CErrors.user_err ?loc:sort.CAst.loc Pp.(str "only explicits sorts are supported")) in
let { ComInductive.template; cumulative; poly; finite } = flags in
if template <> None then nYI "raw template polymorphic inductives";
if udecl <> None then nYI "raw universe polymorphic inductives with universe declaration";
{
name;
parameters = binders;
sort;
constructor = Some idbuild;
fields = cfs;
univpoly = univpoly_of ~poly ~cumulative
}
[%%endif]
let intern_record_decl glob_sign (it : raw_record_decl) = glob_sign, it
let mkCLocalAssum x y z = Constrexpr.CLocalAssum(x,None,y,z)
let dest_entry (_,_,_,_,x) = x
let raw_record_decl_to_glob_synterp ({ name; sort; parameters; constructor; fields; univpoly } : raw_record_decl_elpi) : glob_record_decl_elpi =
let name, space = sep_last_qualid name in
let params = intern_global_context_synterp parameters in
let params = List.rev params in
let arity = mkGHole in
let fields =
List.fold_left (fun acc -> function
| Vernacexpr.AssumExpr ({ CAst.v = name } as fn,bl,x), { Vernacexpr.rf_coercion = inst; rf_priority = pr; rf_notation = nots; rf_canonical = canon } ->
if nots <> [] then Coq_elpi_utils.nYI "notation in record fields";
if pr <> None then Coq_elpi_utils.nYI "priority in record fields";
let atts = { Coq_elpi_HOAS.is_canonical = canon; is_coercion = if inst = Vernacexpr.AddCoercion then Reversible else Off; name } in
let x = if bl = [] then x else Constrexpr_ops.mkCProdN bl x in
let entry = intern_global_context_synterp [mkCLocalAssum [fn] (Constrexpr.Default Glob_term.Explicit) x] in
let x = match entry with
| [x] -> dest_entry x
| _ -> assert false in
(x, atts) :: acc
| Vernacexpr.DefExpr _, _ -> Coq_elpi_utils.nYI "DefExpr")
[] fields in
{ name = (space, Names.Id.of_string name); arity; params; constructorname = constructor; fields = List.rev fields; univpoly }
let expr_Type_sort = Constrexpr_ops.expr_Type_sort
let raw_record_decl_to_glob glob_sign ({ name; sort; parameters; constructor; fields; univpoly } : raw_record_decl_elpi) : glob_record_decl_elpi =
let name, space = sep_last_qualid name in
let sort = match sort with
| Some x -> Constrexpr.CSort x
| None -> Constrexpr.(CSort expr_Type_sort) in
let intern_env, params = intern_global_context glob_sign ~intern_env:Constrintern.empty_internalization_env parameters in
let glob_sign_params = push_glob_ctx params glob_sign in
let params = List.rev params in
let arity = intern_global_constr_ty ~intern_env glob_sign_params @@ CAst.make sort in
let _, _, fields =
List.fold_left (fun (gs,intern_env,acc) -> function
| Vernacexpr.AssumExpr ({ CAst.v = name } as fn,bl,x), { Vernacexpr.rf_coercion = inst; rf_priority = pr; rf_notation = nots; rf_canonical = canon } ->
if nots <> [] then Coq_elpi_utils.nYI "notation in record fields";
if pr <> None then Coq_elpi_utils.nYI "priority in record fields";
let atts = { Coq_elpi_HOAS.is_canonical = canon; is_coercion = if inst = Vernacexpr.AddCoercion then Reversible else Off; name } in
let x = if bl = [] then x else Constrexpr_ops.mkCProdN bl x in
let intern_env, entry = intern_global_context ~intern_env gs [mkCLocalAssum [fn] (Constrexpr.Default Glob_term.Explicit) x] in
let x = match entry with
| [x] -> dest_entry x
| _ -> assert false in
let gs = push_glob_ctx entry gs in
gs, intern_env, (x, atts) :: acc
| Vernacexpr.DefExpr _, _ -> Coq_elpi_utils.nYI "DefExpr")
(glob_sign_params,intern_env,[]) fields in
{ name = (space, Names.Id.of_string name); arity; params; constructorname = constructor; fields = List.rev fields; univpoly }
let raw_indt_decl_to_glob_synterp ({ finiteness; name; parameters; non_uniform_parameters; arity; constructors; univpoly } : raw_indt_decl_elpi) : glob_indt_decl_elpi =
let name, space = sep_last_qualid name in
let name = Names.Id.of_string name in
let params = intern_global_context_synterp parameters in
let nuparams_given, nuparams =
match non_uniform_parameters with
| Some l -> true, l
| None -> false, [] in
let nuparams = intern_global_context_synterp nuparams in
let params = List.rev params in
let nuparams = List.rev nuparams in
let arity = mkGHole in
let constructors = List.map (fun (id,ty) -> id.CAst.v, mkGHole) constructors in
{ finiteness; name = (space, name); arity; params; nuparams; nuparams_given; constructors; univpoly }
let raw_indt_decl_to_glob glob_sign ({ finiteness; name; parameters; non_uniform_parameters; arity; constructors; univpoly } : raw_indt_decl_elpi) : glob_indt_decl_elpi =
let name, space = sep_last_qualid name in
let name = Names.Id.of_string name in
let indexes = match arity with
| Some x -> x
| None -> CAst.make Constrexpr.(CSort expr_Type_sort) in
let intern_env, params = intern_global_context glob_sign ~intern_env:Constrintern.empty_internalization_env parameters in
let nuparams_given, nuparams =
match non_uniform_parameters with
| Some l -> true, l
| None -> false, [] in
let intern_env, nuparams = intern_global_context glob_sign ~intern_env nuparams in
let params = List.rev params in
let nuparams = List.rev nuparams in
let allparams = params @ nuparams in
let user_impls : Impargs.manual_implicits =
if nuparams_given then List.map Coq_elpi_utils.manual_implicit_of_gdecl nuparams
else List.map Coq_elpi_utils.manual_implicit_of_gdecl allparams in
let glob_sign_params = push_glob_ctx allparams glob_sign in
let arity = intern_global_constr_ty ~intern_env glob_sign_params indexes in
let glob_sign_params_self = push_name glob_sign_params (Names.Name name) in
let indty, intern_env = push_inductive_in_intern_env intern_env name allparams arity user_impls in
let constructors =
List.map (fun (id,ty) -> id.CAst.v,
intern_global_constr_ty ~expty:(Pretyping.OfType indty) glob_sign_params_self ~intern_env ty) constructors in
{ finiteness; name = (space, name); arity; params; nuparams; nuparams_given; constructors; univpoly }
let intern_indt_decl glob_sign (it : raw_indt_decl) = glob_sign, it
let expr_hole = CAst.make @@ Constrexpr.CHole(None)
let raw_context_decl_to_glob_synterp fields =
let fields = intern_global_context_synterp fields in
List.rev fields
let raw_context_decl_to_glob glob_sign fields =
let _intern_env, fields = intern_global_context ~intern_env:Constrintern.empty_internalization_env glob_sign fields in
List.rev fields
let intern_context_decl glob_sign (it : raw_context_decl) = glob_sign, it
let raw_decl_name_to_glob name =
let name, space = sep_last_qualid name in
(space, Names.Id.of_string name)
let interp_red_expr = Redexpr.interp_redexp_no_ltac
let raw_constant_decl_to_constr ~depth coq_ctx state { name; typ = (bl,typ); body; red; udecl; atts } =
let env = coq_ctx.env in
let poly =
let open Attributes in
parse polymorphic atts in
let state, udecl =
match udecl, poly with
| None, false -> state, NotUniversePolymorphic
| Some _, false -> nYI "only universe polymorphic definitions can take universe binders"
| None, true -> state, NonCumulative (([],true),(Univ.Constraints.empty,true))
| Some udecl, true ->
let open UState in
let sigma, { univdecl_extensible_instance; univdecl_extensible_constraints; univdecl_constraints; univdecl_instance} =
Constrintern.interp_univ_decl_opt (Coq_elpi_HOAS.get_global_env state) (Some udecl) in
let ustate = Evd.evar_universe_context sigma in
let state = merge_universe_context state ustate in
state, NonCumulative ((univdecl_instance,univdecl_extensible_instance),(univdecl_constraints,univdecl_extensible_constraints)) in
let sigma = get_sigma state in
match body, typ with
| Some body, _ ->
let sigma, red = option_map_acc (interp_red_expr env) sigma red in
let sigma, (body, typ), impargs =
ComDefinition.interp_definition ~program_mode:false
env sigma Constrintern.empty_internalization_env bl red body typ
in
let state, gls0 = set_current_sigma ~depth state sigma in
let typ = option_default (fun () -> Retyping.get_type_of env sigma body) typ in
state, udecl, typ, Some body, gls0
| None, Some typ ->
assert(red = None);
let sigma, typ, impargs =
ComAssumption.interp_assumption ~program_mode:false
env sigma Constrintern.empty_internalization_env bl typ in
let state, gls0 = set_current_sigma ~depth state sigma in
state, udecl, typ, None, gls0
| _ -> assert false
let raw_constant_decl_to_glob_synterp ({ name; atts; udecl; typ = (params,typ); body } : raw_constant_decl) state =
let params = intern_global_context_synterp params in
let params = List.rev params in
let typ = mkGHole in
let body = Option.map (fun _ -> mkGHole) body in
let poly =
let open Attributes in
parse polymorphic atts in
let udecl =
if poly then NonCumulative (([],true),(Univ.Constraints.empty,true))
else NotUniversePolymorphic in
state, { name = raw_decl_name_to_glob name; params; typ; udecl; body }
let raw_constant_decl_to_glob glob_sign ({ name; atts; udecl; typ = (params,typ); body } : raw_constant_decl) state =
let intern_env, params = intern_global_context glob_sign ~intern_env:Constrintern.empty_internalization_env params in
let glob_sign_params = push_glob_ctx params glob_sign in
let params = List.rev params in
let typ = Option.default expr_hole typ in
let typ = intern_global_constr_ty ~intern_env glob_sign_params typ in
let body = Option.map (intern_global_constr ~intern_env glob_sign_params) body in
let poly =
let open Attributes in
parse polymorphic atts in
let state, udecl =
match udecl, poly with
| None, false -> state, NotUniversePolymorphic
| Some _, false -> nYI "only universe polymorphic definitions can take universe binders"
| None, true -> state, NonCumulative (([],true),(Univ.Constraints.empty,true))
| Some udecl, true ->
let open UState in
let sigma, { univdecl_extensible_instance; univdecl_extensible_constraints; univdecl_constraints; univdecl_instance} =
Constrintern.interp_univ_decl_opt (Coq_elpi_HOAS.get_global_env state) (Some udecl) in
let ustate = Evd.evar_universe_context sigma in
let state = merge_universe_context state ustate in
state, NonCumulative ((univdecl_instance,univdecl_extensible_instance),(univdecl_constraints,univdecl_extensible_constraints)) in
state, { name = raw_decl_name_to_glob name; params; typ; udecl; body }
let intern_constant_decl glob_sign (it : raw_constant_decl) = glob_sign, it
let glob glob_sign : raw -> glob = function
| Int _ as x -> x
| String _ as x -> x
| Term t -> Term (intern_tactic_constr glob_sign t)
| RecordDecl t -> RecordDecl (intern_record_decl glob_sign t)
| IndtDecl t -> IndtDecl (intern_indt_decl glob_sign t)
| ConstantDecl t -> ConstantDecl (intern_constant_decl glob_sign t)
| Context c -> Context (intern_context_decl glob_sign c)
let subst _mod_subst _x =
CErrors.anomaly Pp.(str "command arguments should not be substituted")
let interp ist env evd : glob -> top = function
| Int _ as x -> x
| String _ as x -> x
| Term t -> Term(ist,t)
| RecordDecl t -> (RecordDecl(ist,t))
| IndtDecl t -> (IndtDecl(ist,t))
| ConstantDecl t -> (ConstantDecl(ist,t))
| Context c -> (Context(ist,c))
end
module Tac = struct
type raw_term = Constrexpr.constr_expr
type glob_term = Genintern.glob_constr_and_expr
type top_term = Geninterp.interp_sign * Genintern.glob_constr_and_expr
type raw_ltac_term = Constrexpr.constr_expr
type glob_ltac_term = Glob_term.glob_constr
type top_ltac_term = Geninterp.interp_sign * Names.Id.t
type raw_ltac_tactic = Ltac_plugin.Tacexpr.raw_tactic_expr
type glob_ltac_tactic = Ltac_plugin.Tacexpr.glob_tactic_expr
type top_ltac_tactic = Geninterp.Val.t
type ltac_ty = Int | String | Term | List of ltac_ty
type ('a,'f,'t) t =
| Int : int -> ('a,'f,'t) t
| String : string -> ('a,'f,'t) t
| Term : 'a -> ('a,'f,'t) t
| LTac : ltac_ty * 'f -> ('a,'f,'t) t
| LTacTactic : 't -> ('a,'f,'t) t
type raw = (raw_term, raw_ltac_term, raw_ltac_tactic) t
type glob = (glob_term, glob_ltac_term, glob_ltac_tactic) t
type top = (top_term, top_ltac_term, top_ltac_tactic) t
let pr_raw_ltac_arg _ _ _ = Pp.str "TODO: pr_raw_ltac_arg"
let pr_glob_ltac_arg _ _ _ = Pp.str "TODO: pr_glob_ltac_arg"
let pr_top_ltac_arg _ _ _ = Pp.str "TODO: pr_top_ltac_arg"
let pr_raw_ltac_tactic _ _ _ = Pp.str "TODO: pr_raw_ltac_tactic"
let pr_glob_ltac_tactic _ _ _ = Pp.str "TODO: pr_glob_ltac_tactic"
let pr_top_ltac_tactic _ _ _ = Pp.str "TODO: pr_top_ltac_tactic"
let pr_arg f k t x = match x with
| Int n -> Pp.int n
| String s -> Pp.qstring s
| Term s -> f s
| LTac(_, s) -> k s
| LTacTactic s -> t s
let pr_glob_constr_and_expr env sigma = function
| (_, Some c) ->
Ppconstr.pr_constr_expr env sigma c
| (c, None) ->
Printer.pr_glob_constr_env env sigma c
let _pr_glob_constr = Printer.pr_glob_constr_env
let pp_raw env sigma : raw -> Pp.t =
pr_arg
(Ppconstr.pr_constr_expr env sigma)
(pr_raw_ltac_arg env sigma)
(pr_raw_ltac_tactic env sigma)
let pp_glob env sigma =
pr_arg
(pr_glob_constr_and_expr env sigma)
(pr_glob_ltac_arg env sigma)
(pr_glob_ltac_tactic env sigma)
let pp_top env sigma : top -> Pp.t =
pr_arg
((fun (_,x) -> pr_glob_constr_and_expr env sigma x))
(pr_top_ltac_arg env sigma)
(pr_top_ltac_tactic env sigma)
let glob glob_sign : raw -> _ * glob = function
| Int _ as x -> glob_sign, x
| String _ as x -> glob_sign, x
| Term t -> glob_sign, Term (intern_tactic_constr glob_sign t)
| LTac(ty,t) -> glob_sign, LTac (ty,fst @@ intern_tactic_constr glob_sign t)
| LTacTactic t -> glob_sign, LTacTactic (Ltac_plugin.Tacintern.glob_tactic t)
let subst mod_subst = function
| Int _ as x -> x
| String _ as x -> x
| Term t ->
Term (Ltac_plugin.Tacsubst.subst_glob_constr_and_expr mod_subst t)
| LTac(ty,t) ->
LTac(ty,(Detyping.subst_glob_constr (Global.env()) mod_subst t))
| LTacTactic t ->
LTacTactic (Ltac_plugin.Tacsubst.subst_tactic mod_subst t)
let interp return ist = function
| Int _ as x -> return x
| String _ as x -> return x
| Term t -> return @@ Term(ist,t)
| LTac(ty,v) ->
let id =
match DAst.get v with
| Glob_term.GVar id -> id
| _ -> assert false in
return @@ LTac(ty,(ist,id))
| LTacTactic t -> return @@ LTacTactic (Ltac_plugin.Tacinterp.Value.of_closure ist t)
let add_genarg tag pr_raw pr_glob pr_top glob subst interp =
let wit = Genarg.make0 tag in
let tag = Geninterp.Val.create tag in
let () = Genintern.register_intern0 wit glob in
let () = Gensubst.register_subst0 wit subst in
let () = Geninterp.register_interp0 wit (interp (fun x -> Ftactic.return @@ Geninterp.Val.Dyn (tag, x))) in
let () = Geninterp.register_val0 wit (Some (Geninterp.Val.Base tag)) in
Ltac_plugin.Pptactic.declare_extra_genarg_pprule wit pr_raw pr_glob pr_top;
wit
;;
let wit = add_genarg "elpi_ftactic_arg"
(fun env sigma _ _ _ -> pp_raw env sigma)
(fun env sigma _ _ _ -> pp_glob env sigma)
(fun env sigma _ _ _ -> pp_top env sigma)
glob
subst
interp
end
let mk_indt_decl state univpoly r =
match univpoly with
| Cmd.Mono -> state, E.mkApp ideclc r []
| Cmd.Poly ->
let state, up, gls = universe_decl.API.Conversion.embed ~depth:0 state (([],true),(Univ.Constraints.empty,true)) in
assert(gls=[]);
state, E.mkApp uideclc r [up]
| Cmd.CumulPoly ->
let state, up, gls = universe_decl_cumul.API.Conversion.embed ~depth:0 state (([],true),(Univ.Constraints.empty,true)) in
assert(gls=[]);
state, E.mkApp uideclc r [up]
let rec do_params_synterp ~depth params k state =
match params with
| [] -> k state
| (name,imp,ob,src) :: params ->
if ob <> None then Coq_elpi_utils.nYI "defined parameters in a record/inductive declaration";
let src = E.mkDiscard in
let state, tgt = do_params_synterp ~depth params k state in
let state, imp = in_elpi_imp ~depth state imp in
state, in_elpi_parameter name ~imp src tgt
let rec do_fields_synterp ~depth fields state =
match fields with
| [] -> state, in_elpi_indtdecl_endrecord ()
| (f,({ name; is_coercion; is_canonical } as att)) :: fields ->
let f = E.mkDiscard in
let state, fields = do_fields_synterp ~depth fields state in
in_elpi_indtdecl_field ~depth state att f fields
let do_record_synterp ~depth ~name ~constructorname arity fields state =
let space, record_name = name in
let qrecord_name = Id.of_string_soft @@ String.concat "." (space @ [Id.to_string record_name]) in
let arity = E.mkDiscard in
let state, fields = do_fields_synterp ~depth fields state in
let constructor = match constructorname with
| None -> Name.Name (Id.of_string ("Build_" ^ Id.to_string record_name))
| Some x -> Name.Name x in
state, in_elpi_indtdecl_record (Name.Name qrecord_name) arity constructor fields
let grecord2lp_synterp ~depth state { Cmd.name; arity; params; constructorname; fields; univpoly } =
let params = List.map drop_relevance params in
let state, r = do_params_synterp ~depth params (do_record_synterp ~depth ~name ~constructorname arity fields) state in
mk_indt_decl state univpoly r
let grecord2lp ~depth state { Cmd.name; arity; params; constructorname; fields; univpoly } =
let open Coq_elpi_glob_quotation in
let state, r = do_params params (do_record ~name ~constructorname arity fields) ~depth state in
mk_indt_decl state univpoly r
let contract_params env sigma name params nuparams_given t =
if nuparams_given then t else
let open Glob_term in
let loc = Option.map Coq_elpi_utils.of_coq_loc t.CAst.loc in
let rec contract params args =
match params, args with
| [], rest -> rest
| _ :: _, [] ->
Coq_elpi_utils.err ?loc Pp.(str "Inductive type "++ Names.Id.print name ++
str" is not applied to enough parameters. Missing: " ++
prlist_with_sep spc Names.Name.print (List.map (fun (x,_,_,_) -> x) params))
| (Name.Anonymous,_,_,_) :: ps , _ :: rest -> contract ps rest
| (Name.Name pname,_,_,_) :: ps , arg :: rest ->
begin match DAst.get arg with
| GVar v when Names.Id.equal pname v -> contract ps rest
| GHole _ -> contract ps rest
| _ -> Coq_elpi_utils.err ?loc Pp.(str "Inductive type "++ Names.Id.print name ++
str" is not applied to parameter " ++ Names.Id.print pname ++
str" but rather " ++ Printer.pr_glob_constr_env env sigma arg)
end
in
let rec aux x =
match DAst.get x with
| GApp(hd,args) ->
begin match DAst.get hd with
| GVar id when Names.Id.equal id name ->
DAst.make @@ GApp(hd,contract params args)
| _ -> Glob_ops.map_glob_constr aux x
end
| _ -> Glob_ops.map_glob_constr aux x in
aux t
let nogls f ~depth state =
let state, x = f ~depth state in
state, x, ()
let drop_unit f ~depth state =
let state, x, () = f ~depth state in
state, x
let ginductive2lp_synterp ~depth state { Cmd.finiteness; name; arity; params; nuparams; nuparams_given; constructors; univpoly } =
let space, indt_name = name in
let nuparams = List.map drop_relevance nuparams in
let params = List.map drop_relevance params in
let do_constructor ~depth state (name, ty) =
let state, ty = do_params_synterp nuparams (fun state -> state, in_elpi_arity E.mkDiscard) ~depth state in
state, in_elpi_indtdecl_constructor (Name.Name name) ty
in
let do_inductive_synterp ~depth state =
let qindt_name = Id.of_string_soft @@ String.concat "." (space @ [Id.to_string indt_name]) in
let state, arity = do_params_synterp nuparams (fun state -> state, in_elpi_arity E.mkDiscard) ~depth state in
let state, constructors = Coq_elpi_utils.list_map_acc (do_constructor ~depth ) state constructors in
state, in_elpi_indtdecl_inductive state finiteness (Name.Name qindt_name) arity constructors
in
let state, r = do_params_synterp params (do_inductive_synterp ~depth) ~depth state in
mk_indt_decl state univpoly r
let ginductive2lp ~depth state { Cmd.finiteness; name; arity; params; nuparams; nuparams_given; constructors; univpoly } =
let open Coq_elpi_glob_quotation in
let space, indt_name = name in
let contract state x =
let params = List.map drop_relevance params in
contract_params (get_global_env state) (get_sigma state) indt_name params nuparams_given x in
let do_constructor ~depth state (name, ty) =
let state, ty = do_params nuparams (do_arity (contract state ty)) ~depth state in
state, in_elpi_indtdecl_constructor (Name.Name name) ty
in
let do_inductive ~depth state =
let short_name = Name.Name indt_name in
let qindt_name = Id.of_string_soft @@ String.concat "." (space @ [Id.to_string indt_name]) in
let state, term_arity = gterm2lp ~depth state (Coq_elpi_utils.mk_gforall arity nuparams) in
let state, arity = do_params nuparams (do_arity arity) ~depth state in
under_ctx short_name term_arity None (fun ~depth state ->
let state, constructors = Coq_elpi_utils.list_map_acc (do_constructor ~depth ) state constructors in
state, in_elpi_indtdecl_inductive state finiteness (Name.Name qindt_name) arity constructors, ())
~depth state
in
let state, r = do_params params (drop_unit do_inductive) ~depth state in
mk_indt_decl state univpoly r
let in_option = Elpi.(Builtin.option API.BuiltInData.any).API.Conversion.embed
let decl_name2lp name =
let space, constant_name = name in
let qconstant_name =
Id.of_string_soft @@ String.concat "." (space @ [Id.to_string constant_name]) in
in_elpi_id (Name.Name qconstant_name)
let cdeclc = E.Constants.declare_global_symbol "const-decl"
let ucdeclc = E.Constants.declare_global_symbol "upoly-const-decl"
let gdecl2lp_synterp ~depth state { Cmd.name; params; typ : _; body; udecl } =
let params = List.map drop_relevance params in
let state, typ = do_params_synterp ~depth params (fun state -> state, in_elpi_arity E.mkDiscard) state in
let body = Option.map (fun _ -> E.mkDiscard) body in
let name = decl_name2lp name in
let state, body, gls = in_option ~depth state body in
match udecl with
| NotUniversePolymorphic -> state, E.mkApp cdeclc name [body;typ], gls
| Cumulative _ -> assert false
| NonCumulative ud ->
let state, ud, gls1 = universe_decl.API.Conversion.embed ~depth state ud in
state, E.mkApp ucdeclc name [body;typ;ud], gls @ gls1
let cdecl2lp ~depth state { Cmd.name; params; typ; body; udecl } =
let open Coq_elpi_glob_quotation in
let state, typ = do_params params (do_arity typ) ~depth state in
let state, body = option_map_acc (fun state bo -> gterm2lp ~depth state @@ Coq_elpi_utils.mk_gfun bo params) state body in
let name = decl_name2lp name in
let state, body, gls = in_option ~depth state body in
match udecl with
| NotUniversePolymorphic -> state, E.mkApp cdeclc name [body;typ], gls
| Cumulative _ -> assert false
| NonCumulative ud ->
let state, ud, gls1 = universe_decl.API.Conversion.embed ~depth state ud in
state, E.mkApp ucdeclc name [body;typ;ud], gls @ gls1
let ctxitemc = E.Constants.declare_global_symbol "context-item"
let ctxendc = E.Constants.declare_global_symbol "context-end"
let rec do_context_glob_synterp fields ~depth state =
match fields with
| [] -> state, E.mkGlobal ctxendc
| (name,_,bk,bo,ty) :: fields ->
let ty = E.mkDiscard in
let bo = Option.map (fun _ -> E.mkDiscard) bo in
let state, fields = do_context_glob_synterp fields ~depth state in
let state, bo, _ = in_option ~depth state bo in
let state, imp = in_elpi_imp ~depth state bk in
state, E.mkApp ctxitemc (in_elpi_id name) [imp;ty;bo;E.mkLam fields]
let rec do_context_glob fields ~depth state =
match fields with
| [] -> state, E.mkGlobal ctxendc
| (name,_,bk,bo,ty) :: fields ->
let open Coq_elpi_glob_quotation in
let state, ty = gterm2lp ~depth state ty in
let state, bo = option_map_acc (gterm2lp ~depth) state bo in
let state, fields, () = under_ctx name ty bo (nogls (do_context_glob fields)) ~depth state in
let state, bo, _ = in_option ~depth state bo in
let state, imp = in_elpi_imp ~depth state bk in
state, E.mkApp ctxitemc (in_elpi_id name) [imp;ty;bo;E.mkLam fields]
let rec do_context_constr coq_ctx csts fields ~depth state =
let map s x = constr2lp coq_ctx csts ~depth s (EConstr.of_constr x) in
match fields with
| [] -> state, E.mkGlobal ctxendc, []
| (id,bo,ty,bk) :: fields ->
let name = Name id in
let state, ty, gl0 = map state ty in
let state, bo, gl1 = match bo with
| None -> state, None, []
| Some bo -> let state, bo, gl = map state bo in state, Some bo, gl in
(* TODO GLS *)
let state, fields, gl2 = Coq_elpi_glob_quotation.under_ctx name ty bo (do_context_constr coq_ctx csts fields) ~depth state in
let state, bo, gl3 = in_option ~depth state bo in
let state, imp = in_elpi_imp ~depth state bk in
state, E.mkApp ctxitemc (in_elpi_id name) [imp;ty;bo;E.mkLam fields], gl0 @ gl1 @ gl2 @ gl3
let strc = E.Constants.declare_global_symbol "str"
let trmc = E.Constants.declare_global_symbol "trm"
let tacc = E.Constants.declare_global_symbol "tac"
let intc = E.Constants.declare_global_symbol "int"
let ctxc = E.Constants.declare_global_symbol "ctx-decl"
let my_cast_to_string v =
let open Ltac_plugin in
try Taccoerce.Value.cast (Genarg.topwit Stdarg.wit_string) v
with CErrors.UserError _ -> try
Taccoerce.Value.cast (Genarg.topwit Stdarg.wit_ident) v |> Names.Id.to_string
with CErrors.UserError _ ->
raise (Taccoerce.CannotCoerceTo "a string")
let to_list v =
let open Ltac_plugin in
match Taccoerce.Value.to_list v with
| None -> raise (Taccoerce.CannotCoerceTo "a list")
| Some l -> l
(* if we make coq elaborate an arity, we get a type back. here we try to
recoved an arity to pass that to elpi *)
let best_effort_recover_arity ~depth state glob_sign typ bl =
let _, grouped_bl = intern_global_context glob_sign ~intern_env:Constrintern.empty_internalization_env bl in
let rec aux ~depth state typ gbl =
match gbl with
| (name,ik,_,_) :: gbl ->
begin match Coq_elpi_HOAS.is_prod ~depth typ with
| None -> state, in_elpi_arity typ
| Some(ty,bo) ->
let state, imp = in_elpi_imp ~depth state ik in
let state, bo = aux ~depth:(depth+1) state bo gbl in
state, in_elpi_parameter name ~imp ty bo
end
| _ -> state, in_elpi_arity typ
in
aux ~depth state typ (List.map drop_relevance (List.rev grouped_bl))
let in_elpi_string_arg ~depth state x =
state, E.mkApp strc (CD.of_string x) [], []
let in_elpi_int_arg ~depth state x =
state, E.mkApp intc (CD.of_int x) [], []
let in_elpi_term_arg ~depth state coq_ctx hyps sigma ist glob_or_expr =
let closure = Ltac_plugin.Tacinterp.interp_glob_closure ist coq_ctx.env sigma glob_or_expr in
let g = Coq_elpi_utils.detype_closed_glob coq_ctx.env sigma closure in
let state = Coq_elpi_glob_quotation.set_coq_ctx_hyps state (coq_ctx,hyps) in
let state, t = Coq_elpi_glob_quotation.gterm2lp ~depth state g in
state, E.mkApp trmc t [], []
let in_elpi_tac_econstr ~depth ?calldepth coq_ctx hyps sigma state x =
let state, gls0 = set_current_sigma ~depth state sigma in
let state, t, gls1 = Coq_elpi_HOAS.constr2lp ~depth ?calldepth coq_ctx E.no_constraints state x in
state, [E.mkApp trmc t []], gls0 @ gls1
let in_elpi_elab_term_arg ~depth ?calldepth state coq_ctx hyps sigma ist glob_or_expr =
let sigma, t = Ltac_plugin.Tacinterp.interp_open_constr_with_classes ist coq_ctx.env sigma glob_or_expr in
let state, gls0 = set_current_sigma ~depth state sigma in
let state, t, gls1 = constr2lp_closed ~depth ?calldepth coq_ctx E.no_constraints state t in
state, E.mkApp trmc t [], gls0 @ gls1
let singleton (state,x,gls) = state,[x],gls
let rec in_elpi_ltac_arg ~depth ?calldepth coq_ctx hyps sigma state ty ist v =
let open Ltac_plugin in
let open Tac in
let self ty state = in_elpi_ltac_arg ~depth ?calldepth coq_ctx hyps sigma state ty ist in
let self_list ty state l =
try
let state, l, gl = API.Utils.map_acc (self ty) state l in
state, List.flatten l, gl
with Taccoerce.CannotCoerceTo s ->
raise (Taccoerce.CannotCoerceTo (s ^ " list")) in
match (ty : ltac_ty) with
| List (List _) ->
Coq_elpi_utils.err Pp.(str"ltac_<arg>_list_list is not implemented")
| List ty ->
let l = to_list v in
self_list ty state l
| Int ->
let n = Taccoerce.coerce_to_int v in
singleton @@ in_elpi_int_arg ~depth state n
| String ->
let s = my_cast_to_string v in
singleton @@ in_elpi_string_arg ~depth state s
| Term -> try
let t = Taccoerce.Value.cast (Genarg.topwit Stdarg.wit_open_constr) v in
let state, t, gls = constr2lp ~depth ?calldepth coq_ctx E.no_constraints state t in
state, [E.mkApp trmc t []], gls
with CErrors.UserError _ -> try
let closure = Taccoerce.coerce_to_uconstr v in
let g = Coq_elpi_utils.detype_closed_glob coq_ctx.env sigma closure in
let state = Coq_elpi_glob_quotation.set_coq_ctx_hyps state (coq_ctx,hyps) in
let state, t = Coq_elpi_glob_quotation.gterm2lp ~depth state g in
state, [E.mkApp trmc t []], []
with Taccoerce.CannotCoerceTo _ -> try
let id = Taccoerce.coerce_to_hyp coq_ctx.env sigma v in
let state, t, gls = Coq_elpi_HOAS.constr2lp ~depth ?calldepth coq_ctx E.no_constraints state (EConstr.mkVar id) in
state, [E.mkApp trmc t []], gls
with Taccoerce.CannotCoerceTo _ ->
raise (Taccoerce.CannotCoerceTo "a term")
let { CD.cin = of_ltac_tactic; isc = is_ltac_tactic; cout = to_ltac_tactic }, tac = CD.declare {
CD.name = "ltac1-tactic";
doc = "LTac1 tactic expression";
pp = (fun fmt _ -> Format.fprintf fmt "«ltac1-tactic»");
compare = (fun a b -> 0);
hash = (fun x -> Hashtbl.hash x);
hconsed = false;
constants = [];
}
let in_elpi_ltac_tactic ~depth ?calldepth coq_ctx hyps sigma state t =
state, [E.mkApp tacc (of_ltac_tactic t) []], []
let in_elpi_tac ~depth ?calldepth coq_ctx hyps sigma state x =
let open Tac in
match x with
| LTacTactic t -> in_elpi_ltac_tactic ~depth ?calldepth coq_ctx hyps sigma state t
| LTac(ty,(ist,id)) ->
let v = try Id.Map.find id ist.Geninterp.lfun with Not_found -> assert false in
begin try
in_elpi_ltac_arg ~depth ?calldepth coq_ctx hyps sigma state ty ist v
with Ltac_plugin.Taccoerce.CannotCoerceTo s ->
let env = Some (coq_ctx.env,sigma) in
Ltac_plugin.Taccoerce.error_ltac_variable id env v s end
| Int x -> singleton @@ in_elpi_int_arg ~depth state x
| String x -> singleton @@ in_elpi_string_arg ~depth state x
| Term (ist,glob_or_expr) -> singleton @@ in_elpi_term_arg ~depth state coq_ctx hyps sigma ist glob_or_expr
let handle_template_polymorphism = function
| None -> Some false
| Some false -> Some false
| Some true -> err Pp.(str "#[universes(template)] is not supported")
[%%if coq = "8.20"]
let handle_template_polymorphism flags =
let open Vernacentries.Preprocessed_Mind_decl in
{ flags with template = handle_template_polymorphism flags.template }
[%%else]
let handle_template_polymorphism flags =
{ flags with ComInductive.template = handle_template_polymorphism flags.ComInductive.template }
[%%endif]