type var = Var.var
type symbol = Symbol.symbol
type term = Term.term
type clause = Term.clause
let get_equality_clauses () : clause list =
[
Read_tme.to_clause "(X = X).";
Read_tme.to_clause "(Y = X) :- (X = Y).";
Read_tme.to_clause "(X = Z) :- (X = Y), (Y = Z).";
]
let do_symbol (symbol: symbol) (acc: clause list)
(assemble: term -> term -> term -> clause) : clause list =
let int_to_term (i: int) : term =
Term.request_var (Var.create_universal i)
in
let arity =
Symbol.arity symbol
in
let schema =
Array.make arity 0
in
for i = 0 to Array.length schema - 1 do
schema.(i) <- i;
done;
let rec do_at (index: int) (acc: clause list) : clause list =
if index >= arity then
acc
else begin
let left_term =
Term.request_func (symbol, Array.map int_to_term schema)
in
schema.(index) <- arity;
let right_term =
Term.request_func (symbol, Array.map int_to_term schema)
in
schema.(index) <- index;
let equality_term =
Term.request_func
(Symbol.equality, [| int_to_term index; int_to_term arity |])
in
let clause =
assemble left_term right_term equality_term
in
do_at (index + 1) (clause :: acc)
end
in
do_at 0 acc
let get_predicate_substitutions (symbols: symbol list) : clause list =
let assemble left right equal =
let left_predicate =
Term.request_literal true left
and right_predicate =
Term.request_literal false right
and equality_predicate =
Term.request_literal false equal
in
[ left_predicate; right_predicate; equality_predicate ]
in
List.fold_left
(fun acc symbol ->
do_symbol symbol acc assemble
)
[]
symbols
let get_function_substitutions (symbols : symbol list) : clause list =
let assemble left right equal =
let left_equality_term =
Term.request_func (Symbol.equality, [| left; right |])
in
let left_equality_predicate =
Term.request_literal true left_equality_term
in
let right_equality_predicate =
Term.request_literal false equal
in
[ left_equality_predicate; right_equality_predicate ]
in
List.fold_left
(fun acc symbol ->
do_symbol symbol acc assemble
)
[]
symbols
let get_axioms ~(print_axioms: bool) (problem: Problem.problem) : clause list =
let predicate_symbols, function_symbols =
problem#getPredicateSymbols, problem#getFunctionSymbols
in
let axioms =
get_equality_clauses ()
and predicate_substitutions =
get_predicate_substitutions predicate_symbols
and function_substitutions =
get_function_substitutions function_symbols
in
if print_axioms then begin
print_endline ("Equality Axioms:");
List.iter (fun clause -> print_endline (Term.clause_to_string clause)) axioms;
print_newline ();
if List.length predicate_substitutions > 0 then begin
print_endline ("Predicate Substitution Axioms:");
List.iter (fun clause -> print_endline (Term.clause_to_string clause)) predicate_substitutions;
print_newline ();
end;
if List.length function_substitutions > 0 then begin
print_endline ("Function Substitution Axioms:");
List.iter (fun clause -> print_endline (Term.clause_to_string clause)) function_substitutions;
print_newline ();
end;
print_newline ();
end;
axioms @ predicate_substitutions @ function_substitutions