| OptType ty, OptValue (Some v) -> aux ((name, (ty, v)) :: acc) tl
| _ -> assert false)
| _ :: tl -> aux acc tl
+ (* some pattern may contain only meta names, thus we trash all others *)
+ | [] -> acc
+ in
+ aux [] env
+
+let head_names names env =
+ let rec aux acc = function
+ | (name, (ty, v)) :: tl when List.mem name names ->
+ (match ty, v with
+ | ListType ty, ListValue (v :: _) -> aux ((name, (ty, v)) :: acc) tl
+ | _ -> assert false)
+ | _ :: tl -> aux acc tl
+ (* base pattern may contain only meta names, thus we trash all others *)
+ | [] -> acc
+ in
+ aux [] env
+
+let tail_names names env =
+ let rec aux acc = function
+ | (name, (ty, v)) :: tl when List.mem name names ->
+ (match ty, v with
+ | ListType ty, ListValue (_ :: vtl) ->
+ aux ((name, (ListType ty, ListValue vtl)) :: acc) tl
+ | _ -> assert false)
+ | binding :: tl -> aux (binding :: acc) tl
| [] -> acc
in
aux [] env
| FreshVar _ -> ()
| Ascription _ -> assert false
and aux_magic = function
+ | Default (t1, t2)
| Fold (_, t1, _, t2) ->
aux t1 ;
aux t2
- | Default (t1, t2) ->
- aux t1 ;
- aux t2
| _ -> assert false
in
aux term ;
!names
+let pp_term = ref (fun (t:CicNotationPt.term) -> assert false; "")
+let set_pp_term f = pp_term := f
+
let instantiate ~env term =
let fresh_env = ref [] in
let lookup_fresh_name n =
aux (unopt_names names env) some_pattern
| OptValue None -> aux env none_pattern
| _ -> assert false))
- | Fold _ -> failwith "not yet implemented" (* TODO Fold *)
+ | Fold (`Left, base_pattern, names, rec_pattern) ->
+ let acc_name = List.hd names in (* names can't be empty, cfr. parser *)
+ let meta_names =
+ List.filter ((<>) acc_name) (meta_names_of rec_pattern)
+ in
+ (match meta_names with
+ | [] -> assert false (* as above *)
+ | (name :: _) as names ->
+ let rec instantiate_fold_left acc env' =
+ prerr_endline "instantiate_fold_left";
+ match lookup_value ~env:env' name with
+ | ListValue (_ :: _) ->
+ instantiate_fold_left
+ (let acc_binding = acc_name, (TermType, TermValue acc) in
+ aux (acc_binding :: head_names names env') rec_pattern)
+ (tail_names names env')
+ | ListValue [] -> acc
+ | _ -> assert false
+ in
+ instantiate_fold_left (aux env base_pattern) env)
+ | Fold (`Right, base_pattern, names, rec_pattern) ->
+ let acc_name = List.hd names in (* names can't be empty, cfr. parser *)
+ let meta_names =
+ List.filter ((<>) acc_name) (meta_names_of rec_pattern)
+ in
+ (match meta_names with
+ | [] -> assert false (* as above *)
+ | (name :: _) as names ->
+ let rec instantiate_fold_right env' =
+ prerr_endline "instantiate_fold_right";
+ match lookup_value ~env:env' name with
+ | ListValue (_ :: _) ->
+ let acc = instantiate_fold_right (tail_names names env') in
+ let acc_binding = acc_name, (TermType, TermValue acc) in
+ aux (acc_binding :: head_names names env') rec_pattern
+ | ListValue [] -> aux env base_pattern
+ | _ -> assert false
+ in
+ instantiate_fold_right env)
| _ -> assert false
in
aux env term