type polarity = Pos | Neg | Null let string_of_polarity = function | Pos -> "+" | Neg -> "-" | Null -> "" let string_of_polsym (p, f) = (string_of_polarity p) ^ f module StellarSig = struct type idvar = string type idfunc = polarity * string let concat = (^) let compatible f g = match f, g with | (Pos, f), (Neg, g) | (Neg, f), (Pos, g) when f = g -> true | (Null, f), (Null, g) when f = g -> true | _ -> false let string_of_idfunc = string_of_polsym end module StellarRays = Unification.Make(StellarSig) open StellarSig open StellarRays open Tools (* --------------------------------------- Stars and Constellations --------------------------------------- *) type ray = term type star = ray list type constellation = star list let to_var x = Var x let to_func (pf, ts) = Func (pf, ts) let pos f = (Pos, f) let neg f = (Neg, f) let null f = (Null, f) let pfunc f ts = Func (pos f, ts) let nfunc f ts = Func (neg f, ts) let func f ts = Func (null f, ts) let var x = Var x let pconst f = pfunc f [] let nconst f = nfunc f [] let const f = func f [] let rec is_polarised r : bool = let aux = (function | (Pos, _) | (Neg, _) -> true | (Null, _) -> false) in exists_term_func aux r (* --------------------------------------- Display --------------------------------------- *) let rec string_of_list printer sep = function | [] -> "" | [x] -> printer x | h::t -> (printer h) ^ sep ^ (string_of_list printer sep t) let rec string_of_ray = function | Var x -> x | Func (pf, []) -> string_of_polsym pf | Func ((Null, "."), [r1; r2]) -> (string_of_ray r1) ^ " ยท " ^ (string_of_ray r2) | Func (pf, ts) -> string_of_polsym pf ^ "(" ^ (string_of_list string_of_ray ", " ts) ^ ")" let string_of_subst sub = "{" ^ (List.fold_left ( fun acc (x, r) -> x ^ "->" ^ (string_of_ray r) ) "" sub) ^ "}" let string_of_star s = "[" ^ (string_of_list string_of_ray ", " s) ^ "]" let string_of_constellation cs = if cs = [] then "{}" else string_of_list string_of_star " + " cs let string_of_intspace (cs, space) = (string_of_constellation cs) ^ " |- " ^ (string_of_constellation space) (* --------------------------------------- Interactive execution --------------------------------------- *) let raymatcher ?(withloops=true) r r' : substitution option = if is_polarised r && is_polarised r' then solution ~withloops [(r, r')] else None let interaction ?(withloops=true) (s : star) i j (cs : constellation) : constellation = cs >>= fun i' s' -> let s = List.map (extends_vars i) s in let s' = List.map (extends_vars i') s' in s' >>= fun j' r' -> match raymatcher ~withloops (List.nth s j) r' with | None -> [] | Some sub -> let s1 = without j s in let s2 = without j' s' in return (List.map (subst sub) (s1@s2)) let intspace ?(withloops=true) cs space : constellation = List.flatten ( space >>= fun i s -> s >>= fun j _ -> return (interaction ~withloops s i j (cs@space)) ) let rec intexec ?(withloops=true) (cs, space) : constellation = let result = intspace ~withloops cs space in if result = [] then space else intexec ~withloops (cs, result)