(*
This file is part of the first order theorem prover Darwin
Copyright (C) 2006
The University of Iowa
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*)
type term = Term.term
type literal = Term.literal
module LiteralTable = Term.LiteralTable
(* pseudo-context literal to regress,
used to mark the regression task of the closing clause. *)
let close_literal =
Term.request_literal
true
(Term.request_const Symbol.lemma_root)
(* accepts a list of literal lists,
where each literal is the class of all regressed instances of the same context literal.
simplifies by trying to unify and reduce all instances of a class to a singleton *)
let simplify (regressed: literal list list) : literal list =
let rec simplify (simplified: literal list) (classes: literal list list) =
match classes with
| [] ->
simplified
| literals :: tail ->
begin
try
(* try to unify all literals in this class by unifying its literals pairwise *)
let unifier =
let rec unify' unifier literals =
match literals with
| [] ->
failwith "Lemma: simplifying empty class"
| _ :: [] ->
unifier
| l1 :: l2 :: tail ->
let unifier' =
Unification.unify_literals_ ~recompute:false unifier l1 0 l2 0
in
unify' unifier' (l2 :: tail)
in
unify' Subst.empty literals
in
(* already a singleton, or only constants *)
if Subst.is_empty unifier then begin
simplify (literals @ simplified) tail
end
(* apply unifier to all literals -
have to avoid independent normalization *)
else begin
(* only need to use one literal of the unified class *)
let simplified' =
List.map
(fun literal ->
Subst.apply_to_literal ~normalize:false unifier literal 0
)
((List.hd literals) :: simplified)
in
let classes' =
List.map
(fun literals ->
List.map
(fun literal ->
Subst.apply_to_literal ~normalize:false unifier literal 0
)
literals
)
tail
in
simplify simplified' classes'
end
with
| Unification.UNIFICATION_FAIL ->
(* simplification of this class failed *)
simplify (literals @ simplified) tail
end
in
simplify [] regressed