let simplify ~(print:bool) ~(equality:bool) (clauses: clause list) : clause list * literal list =
if print then begin
print_endline ("Preprocessing: Pure Literals");
end;
(* for equality we can not go by unification,
or perhaps somewhat if we take sorts (Sort_inference) into account.
currently pure is detected by predicate symbol polarity only.
*)
if equality then begin
(* keep from each predicate symbol a mapping index -> contained in claused *)
let index =
Term.LiteralTypeTable.create 1024
in
(* now register all clauses *)
List.iter
(fun clause ->
List.iter
(fun literal ->
let entry =
try
Term.LiteralTypeTable.find index literal
with
| Not_found ->
let new_entry =
ref []
in
Term.LiteralTypeTable.add index literal new_entry;
new_entry
in
entry := clause :: !entry;
)
clause
)
clauses;
(* all unifiable literals must be from the clause itself *)
let is_pure (clause: clause) (literal: literal) : bool =
let matching =
Term.LiteralTypeTable.find index (Term.request_negated_literal literal)
in
List.for_all
(fun clause' -> clause == clause')
!matching
in
(* now check for each clause if one of its literals is pure,
i.e. its negation is not unifiable with a literal from another clause. *)
let purified, pure_literals =
purify ~print:print ~fix:true is_pure clauses
in
if print then begin
print_newline ();
end;
purified, pure_literals
end
(* purity check via unifying literals *)
else begin
(* keep from each literal a mapping index -> contained in claused *)
let index =
Discrimination_tree.create_clause_index false
in
(* now register all clauses *)
List.iter
(fun clause ->
List.iter
(fun literal ->
(index#find literal)#add literal.Term.atom clause
)
clause
)
clauses;
(* all unifiable literals must be from the clause itself *)
let is_pure (clause: clause) (literal: literal) : bool =
let unifiable =
(index#find (Term.request_negated_literal ~insert_db:false literal))#find_all_unifiable
~p_preserving:false literal.Term.atom
in
List.for_all
(fun clause' -> clause == clause')
unifiable
in
(* now check for each clause if one of its literals is pure,
i.e. its negation is not unifiable with a literal from another clause. *)
let purified, pure_literals =
purify ~print:print ~fix:false is_pure clauses
in
if print then begin
print_newline ();
end;
purified, pure_literals
end