type term = Term.term
type literal = Term.literal
type clause = Term.clause
type subst = Subst.subst
type pureness = {
vars: int;
pars: int;
}
let is_universal (pureness: pureness) : bool =
pureness.pars = 0
let is_mixed (pureness: pureness) : bool =
pureness.vars > 0 && pureness.pars > 0
let is_parametric (pureness: pureness) : bool =
pureness.pars > 0
let rec is_term_parametric (term: term) : bool =
match term with
| Term.Var var ->
Var.is_parametric var
| Term.Const _ ->
false
| Term.Func func ->
Tools.array_exists is_term_parametric func.Term.subterms
let is_propositional (literal: literal) =
match literal.Term.atom with
| Term.Const _ ->
true
| Term.Var _
| Term.Func _ ->
false
let cmp_pureness (first: pureness) (second: pureness) : int =
if is_universal first == is_universal second then
0
else if is_universal first then
-1
else
1
let cmp_universality (first: pureness) (second: pureness) : int =
if first.pars < second.pars then
-1
else if first.pars > second.pars then
1
else
compare second.vars first.vars
let get_pureness (term: term) : pureness =
let vars = ref 0
and pars = ref 0
in
let rec do_get_pureness (term: term) : unit =
match term with
| Term.Func func ->
Array.iter
do_get_pureness
func.Term.subterms
| Term.Var var ->
if Var.is_universal var then
vars := !vars + 1
else
pars := !pars + 1
| Term.Const _ ->
()
in
do_get_pureness term;
{
vars = !vars;
pars = !pars;
}
let rec depth_of_term (term: term) (depth: int) : int =
match term with
| Term.Var _ ->
depth
| Term.Const _ ->
depth
| Term.Func func ->
let current_depth =
depth + 1
in
Array.fold_left
(fun acc term ->
Tools.max_int acc (depth_of_term term current_depth)
)
current_depth
func.Term.subterms
let depth_of_literal (literal: literal) =
depth_of_term literal.Term.atom 0
let depth_of_term (term: term) =
depth_of_term term 0
let rec depth_of_term_subst (subst: subst) (term: term) (offset: int) (depth: int) : int =
match term with
| Term.Var var ->
begin
match Subst.get' subst var offset with
| None ->
depth
| Some bound_term ->
depth_of_term_subst subst bound_term.Subst.st_term bound_term.Subst.st_offset depth
end
| Term.Const _ ->
depth
| Term.Func func ->
let current_depth =
depth + 1
in
(Array.fold_left
(fun acc term ->
Tools.max_int acc (depth_of_term_subst subst term offset current_depth)
)
current_depth
func.Term.subterms
)
let depth_of_literal_subst (literal: literal) (subst: subst) (offset: int) =
depth_of_term_subst subst literal.Term.atom offset 0
let rec weight_of_term (term: term) (weight: int) : int =
match term with
| Term.Var _var ->
weight
| Term.Const _ ->
weight + 1
| Term.Func func ->
Array.fold_left
(fun acc term ->
weight_of_term term acc
)
(weight + 1)
func.Term.subterms
let weight_of_literal (literal: literal) : int =
weight_of_term literal.Term.atom 0
let rec weight_of_term_subst (subst: subst) (term: term) (offset: int) (weight: int) : int =
match term with
| Term.Var var ->
begin
match Subst.get' subst var offset with
| None ->
weight
| Some bound_term ->
weight_of_term_subst subst bound_term.Subst.st_term bound_term.Subst.st_offset weight
end
| Term.Const _ ->
weight + 1
| Term.Func func ->
Array.fold_left
(fun acc term ->
weight_of_term_subst subst term offset acc
)
(weight + 1)
func.Term.subterms
let weight_of_literal_subst (literal: literal) (subst: subst) (offset: int) =
weight_of_term_subst subst literal.Term.atom offset 0
let weight_of_clause (clause: clause) : int =
List.fold_left
(fun weight literal -> weight + weight_of_literal literal)
0
clause