let arity_of_x = max_arity_tms x (all_terms p) in
(if arity_of_x < 0 then failwithProblem p "step on a var of negative arity");
(* AC: FIXME compute arities correctly below! *)
- let arities = Array.to_list (Array.make (n+1) 0) in
+ let arities = Num.compute_arities x (n+1) (all_terms p :> nf list) in
+ (* let arities = Array.to_list (Array.make (n+1) 0) in *)
let p,vars = make_fresh_vars p arities in
(* let p,zero = make_fresh_var p in *)
(* let zero = Listx.Nil zero in *)
1:11m42 2:14m5 3:11m16s 4:14m46s 5:12m7s 6:6m31s *)
let x =
try
- match hd_of (List.find (fun t -> compute_special_k (Listx.Nil (t :> nf)) > 0 && arity_of_hd t >= 0) (all_terms p)) with
+ match hd_of (List.find (fun t ->
+ compute_special_k (Listx.Nil (t :> nf)) > 0 && arity_of_hd t >= 0
+ ) (all_terms p)) with
None -> assert false
| Some x ->
prerr_endline ("INSTANTIATING AND HOPING " ^ string_of_var x);
(********************** problems *******************)
-let zero = `Var(0,-1);;
+let zero = `Var(0,0);;
let append_zero =
function
prerr_endline (print (t :> nf));
assert false (* algorithm failed *)
+let set_arity arity = function
+| `Var(n,_) -> `Var(n,arity)
+| `Lam(false, `N _)
+| `Lam(false, `Lam _) as t -> t
+| `Lam(false, `Match(t,(n,ar),bs_lift,bs,args)) -> `Lam(false, `Match(t,(n,arity),bs_lift,bs,args))
+| _ -> assert false
+
let rec mk_app (h : nf) (arg : nf) =
(*let res =*)
match h with
and mk_appx h args = Listx.fold_left mk_app h args
-and mk_match t ar bs_lift bs args =
+and mk_match t (n,ar) bs_lift bs args =
(*prerr_endline ("MK_MATCH: ([" ^ print t ^ "] " ^ String.concat " " (Listx.to_list (Listx.map (fun (n,t) -> string_of_int n ^ " => " ^ print t) bs)) ^ ") " ^ String.concat " " (List.map print args));*)
match t with
`N m ->
(try
let h = List.assoc m !bs in
+ let h = set_arity (ar-1) h in
let h = lift bs_lift h in
mk_appl h args
with Not_found ->
- `Match (t,ar,bs_lift,bs,args))
- | `I _ | `Var _ | `Match _ -> `Match(t,ar,bs_lift,bs,args)
+ `Match (t,(n,ar),bs_lift,bs,args))
+ | `I _ | `Var _ | `Match _ -> `Match(t,(n,ar),bs_lift,bs,args)
and subst delift_by_one what (with_what : nf) (where : nf) =
+ let aux_propagate_arity ar = function
+ | `Lam(false,`Match(`I(v,args),(x,_),liftno,bs,args')) ->
+ `Lam(false,`Match(`I(v,args),(x,ar),liftno,bs,args'))
+ | _ as t -> t in
let rec aux_i_num_var l =
function
`I((n,ar),args) ->
if n = what + l then
- mk_appx (lift l with_what) (Listx.map (aux l) args)
+ mk_appx (lift l (aux_propagate_arity ar with_what)) (Listx.map (aux l) args)
else
`I (((if delift_by_one && n >= l then n-1 else n), ar), Listx.map (aux l) args)
| `Var(n,ar) ->
if n = what + l then
- lift l with_what
+ lift l (aux_propagate_arity ar with_what)
else
`Var((if delift_by_one && n >= l then n-1 else n), ar)
| `N _ as x -> x
List.fold_left (fun acc t -> Pervasives.max acc (aux l t)) ~-1 in
fun tms -> aux_tms 0 (tms :> nf list)
;;
+
+let get_first_args var =
+let rec aux l = function
+| `Lam(_,t) -> aux (l+1) t
+| `Match(u,orig,liftno,bs,args) -> Util.concat_map (aux l) args
+| `I((n,_), args) -> if n = var + l then [Listx.last args] else []
+| `N _
+| `Var _ -> []
+in aux 0
+;;
+
+let compute_arities m =
+ let rec aux n tms =
+ if n = 0
+ then []
+ else
+ let tms = Util.filter_map (function `Lam(_,t) -> Some t | _ -> None ) tms in
+ let arity = max 0 (max_arity_tms (m-n) tms) in (* FIXME: 0 or -1 ??? *)
+ arity :: (aux (n-1) tms)
+ in fun tms -> List.rev (aux m tms)
+;;
+
+let compute_arities var special_k all_tms =
+ let tms = List.fold_left (fun acc t -> acc @ (get_first_args var t)) [] all_tms in
+ compute_arities special_k tms
+;;