let rec lookup s a =
match a with
| Var _ ->
v s a
| App(f, _) ->
let i = Th.of_sym f in
try
let x =
if Th.eq i Th.pprod then
inv_pprod s a
else
inv i s a
in
v s x
with
Not_found -> a
(** Search for largest match on rhs. For example, if a is
of the form x * y and there is an equality u = x^2 * y ,
then inv_pprod s a returns u * x if there is no larger
rhs which matches a . *) |
and inv_pprod s a =
let rec usea acc =
match a with
| App(Pp(Mult), xl) ->
(List.fold_left
(fun acc' x ->
let (x', _) = Pp.destruct x in
Set.union (use Th.pprod s x') acc')
acc xl)
| App(Pp(Expt(_)), [x]) ->
use Th.pprod s x
| _ ->
acc
in
let lookup =
Set.fold
(fun x acc ->
try
let b = apply Th.pprod s x in
(match acc with
| None -> (* [lcm = p * a = q * b = q * x] *)
let (p, q, lcm) = Pp.lcm (a, b) in
if Pp.is_one p then Some(q, x, b) else None
| Some(_, _, b') when Pp.cmp b b' <= 0 ->
acc
| _ ->
let (p, q, lcm) = Pp.lcm (a, b) in
if Pp.is_one p then Some(q, x, b) else acc)
with
Not_found -> acc)
(usea Set.empty)
None
in
match lookup with
| Some(q, x, _) ->
let a' = Pp.mk_mult q (v s x) in
inv_pprod s a'
| None ->
a