123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257openAlba_coreopenAstmoduleInductive_parser=Parser_lang.Make(structtypet=Source_entry.inductivearrayend)moduleExpression_parser=Parser_lang.Make(Expression)letadd_inductive(src:string)(c:Context.t):(Context.t,Build_problem.t)result=letopenInductive_parserinletp=run(inductive_family())srcinassert(has_endedp);assert(has_succeededp);matchresultpwith|None->assertfalse|Someinds->Builder.add_inductiveindscletbuild_expression(src:string)(c:Context.t):(Term.t*Term.typ,Build_problem.t)result=letopenExpression_parserinletp=run(expression())srcinassert(has_endedp);assert(has_succeededp);matchresultpwith|None->assertfalse(* Syntax error *)|Someexp->Build_expression.buildexpc(* Test the inductive types
------------------------
- same number of parameters
- same parameter names
- same parameter types
- inductive type must be a type (i.e. its type a kind)
*)let%test_=letsrc="class I0 A :=\n\
class I1 A B :="inmatchadd_inductivesrcContext.emptywith|Error(_,Build_problem.Wrong_parameter_count_)->true|_->falselet%test_=letsrc="class I0 A :=\n\
class I1 B :="inmatchadd_inductivesrcContext.emptywith|Error(_,Build_problem.Wrong_parameter_name_)->true|_->falselet%test_=letsrc="class I0 (A: Any -> Any) :=\n\
class I1 A :="inmatchadd_inductivesrcContext.emptywith|Error(_,Build_problem.Wrong_parameter_type_)->true|_->falselet%test_=letsrc="class i A: Int :="andcontext=Context.(empty|>add_builtin_type"int_type""Int"Term.any)inmatchadd_inductivesrccontextwith|Error(_,Build_problem.No_inductive_type)->true|_->falselet%test_=letsrc="class I :=\n\
class I :="inmatchadd_inductivesrcContext.emptywith|Error(_,Build_problem.Duplicate_inductive)->true|_->false(* Test the constructors
------------------------
- no duplicate constructor names
- if there are indices, then type must be explicit
- construct a object of the corresponding inductive type
- positivity
- positivity in family
- positivity with other inductive type
*)let%test_=letsrc="class I := c; c"inmatchadd_inductivesrcContext.emptywith|Error(_,Build_problem.Duplicate_constructor)->true|_->falselet%test_=letsrc="class I A: A -> Any := constr"inmatchadd_inductivesrcContext.emptywith|Error(_,Build_problem.Missing_inductive_type)->true|_->falselet%test_=letsrc="class I A := Constr: Any"inmatchadd_inductivesrcContext.emptywith|Error(_,Build_problem.Wrong_type_constructed_)->true|_->falselet%test_=letsrc="class I A := constr: I Proposition"inmatchadd_inductivesrcContext.emptywith|Error(_,Build_problem.Wrong_type_constructed_)->true|_->falselet%test_=letsrc="class I := constr: (I -> Proposition) -> I"inmatchadd_inductivesrcContext.emptywith|Error(_,Build_problem.Negative)->true|_->falselet%test_=letsrc="class I A := constr: I (I A) -> I A"inmatchadd_inductivesrcContext.emptywith|Error(_,Build_problem.Not_positive_)->true|_->falselet%test_=letsrc1="class I1 A := co1: (A -> A) -> I1 A"andsrc2="class I := co : I1 I -> I"inmatchadd_inductivesrc1Context.emptywith|Error_->false|Okc->matchadd_inductivesrc2cwith|Error(_,Build_problem.Nested_negative_)->true|_->falselet%test_=letopenFmlib.Resultinletsrc1="Any -> Any"andsrc2="class II := co : TC II -> II"inmatch(build_expressionsrc1Context.empty>>=fun(typ,_)->add_inductivesrc2(Context.(add_builtin_type"TC""TC"typempty)))with|Error(_,Not_positive_)->true|_->false