Sindbad~EG File Manager
/*
* paramod.c -- Paramodulation inference rules.
*
*/
#include "header.h"
#include "beta.h" // Beeson 8.10.03
#include "unify2.h" // Beeson 8.13.03
#include "bsym.h" // Beeson 7.1.05
#include "fsubsto.h" // Beeson 7.1.05
// #define DIAGNOSTICS // to see diagnostic printout
/*************
*
* struct term *apply_substitute(t, into_term, into_subst, beta, from_subst)
*
* This routine is similar to apply, except that when it reaches the into
* term, the appropriate instance of beta is returned.
*
*************/
static struct term *apply_substitute(struct term *t,
struct term *into_term,
struct context *into_subst,
struct term *beta,
struct context *from_subst,
int *pos_vec,
int *pi)
{
struct term *t2;
struct rel *r1, *r2, *r3;
if (t == into_term)
return(apply(beta, from_subst));
else if (t->type != COMPLEX) {
if (Flags[PARA_ALL].val == 0) {
print_term_nl(stdout, t);
abend("apply_substitute, term not COMPLEX.");
}
return(apply(t, into_subst));
}
else {
int i;
t2 = get_term();
t2->type = COMPLEX;
t2->sym_num = t->sym_num;
r3 = NULL;
for(r1 = t->farg, i = 1; r1; r1 = r1->narg, i++) {
r2 = get_rel();
if (r3 == NULL)
t2->farg = r2;
else
r3->narg = r2;
/* if we are on the path to the into term || PARA_ALL */
if (r1->path || Flags[PARA_ALL].val) {
if (*pi == MAX_FS_TERM_DEPTH)
abend("apply_substitute: term too deep.");
pos_vec[*pi] = i;
(*pi)++;
r2->argval = apply_substitute(r1->argval, into_term,
into_subst, beta, from_subst,
pos_vec, pi);
}
else
r2->argval = apply(r1->argval, into_subst);
r3 = r2;
}
return(t2);
}
} /* apply_substitute */
/*************
*
* struct clause *build_bin_para(alpha, from_subst, into_term, into_lit, into_subst)
*
* Construct a binary paramodulant.
*
*************/
static struct clause *build_bin_para(struct term *alpha,
struct context *from_subst,
struct term *into_term,
struct literal *into_lit,
struct context *into_subst,
int *pos_vec,
int *pi)
{
struct clause *paramodulant;
struct literal *lit, *new, *prev;
struct term *from_atom, *beta;
struct int_ptr *ip0, *ip1, *ip2;
int i;
paramodulant = get_clause();
prev = NULL;
from_atom = alpha->occ.rel->argof; /* find beta */
if (from_atom->farg->argval == alpha)
beta = from_atom->farg->narg->argval; /* beta is second arg */
else
beta = from_atom->farg->argval; /* beta is first arg */
*pi = 1;
/* go through literals of into clause */
for (lit = into_lit->container->first_lit, i = 1; lit; lit = lit->next_lit, i++) {
new = get_literal();
new->container = paramodulant;
if (prev == NULL)
paramodulant->first_lit = new;
else
prev->next_lit = new;
prev = new;
new->sign = lit->sign;
if (lit == into_lit || Flags[PARA_ALL].val) {
pos_vec[0] = i;
new->atom = apply_substitute(lit->atom, into_term, into_subst,
beta, from_subst, pos_vec, pi);
}
else
new->atom = apply(lit->atom, into_subst);
new->atom->occ.lit = new;
new->atom->varnum = lit->atom->varnum; /* copy type of atom */
}
/* go through literals of from clause */
for (lit = from_atom->occ.lit->container->first_lit; lit; lit = lit->next_lit) {
if (lit->atom != from_atom) { /* omit instance of from literal */
new = get_literal();
new->container = paramodulant;
if (paramodulant->first_lit == NULL)
paramodulant->first_lit = new;
else
prev->next_lit = new;
prev = new;
new->sign = lit->sign;
new->atom = apply(lit->atom, from_subst);
new->atom->occ.lit = new;
new->atom->varnum = lit->atom->varnum; /* copy type of atom */
}
}
ip0 = get_int_ptr(); /* rule and parents: to be filled in by caller */
ip1 = get_int_ptr();
ip2 = get_int_ptr();
ip0->next = ip1;
ip1->next = ip2;
paramodulant->parents = ip0;
return(paramodulant);
} /* build_bin_para */
/*************
*
* insert_detailed_para_history()
*
*************/
static void insert_detailed_para_history(struct int_ptr *ip_from,
struct int_ptr *ip_into,
struct term *alpha,
int *pos_vec,
int pos_vec_size)
{
struct int_ptr *ip2, *ip3, *ip4;
int i;
/* Insert position of into term */
ip2 = get_int_ptr();
ip2->i = LIST_RULE - pos_vec_size;
ip4 = ip_into->next;
ip_into->next = ip2;
for (i = 0; i < pos_vec_size; i++) {
ip3 = get_int_ptr();
ip3->i = pos_vec[i];
ip2->next = ip3;
ip2 = ip3;
}
ip2->next = ip4;
/* Insert position of alpha. */
ip2 = get_int_ptr();
ip3 = get_int_ptr();
ip4 = get_int_ptr();
ip2->next = ip3;
ip3->next = ip4;
ip2->i = LIST_RULE - 2;
ip3->i = literal_number(alpha->occ.rel->argof->occ.lit);
ip4->i = (alpha->occ.rel->argof->farg->argval == alpha ? 1 : 2);
ip4->next = ip_from->next;
ip_from->next = ip2;
} /* insert_detailed_para_history */
/*************
*
* para_from_up(t, into_term, into_subst, alpha, from_subst)
*
* We are paramodulating from the given clause, and a clashable into term
* has been found. This routine recursively goes through the clashable
* superterms of the into term.
*
*************/
static void para_from_up(struct term *t,
struct term *into_term,
struct context *into_subst,
struct term *alpha,
struct context *from_subst)
{
struct clause *paramodulant, *from_parent;
struct rel *r;
struct int_ptr *ip;
int pos_vec[MAX_FS_TERM_DEPTH];
int pos_vec_size;
from_parent = alpha->occ.rel->argof->occ.lit->container;
if (t->type == COMPLEX && t->varnum != 0) { /* it's an atom */
if (Flags[PARA_INTO_UNITS_ONLY].val == 0 ||
unit_clause(t->occ.lit->container)) {
paramodulant = build_bin_para(alpha, from_subst, into_term,
t->occ.lit, into_subst,
pos_vec, &pos_vec_size);
if(Flags[LAMBDA_FLAG].val && !check_lambdas(paramodulant)) // Beeson 8.13.03
return; // Beeson 8.13.03
/* fill in derivation info */
ip = paramodulant->parents;
ip->i = PARA_FROM_RULE;
ip->next->i = from_parent->id;
ip->next->next->i = t->occ.lit->container->id;
if (Flags[DETAILED_HISTORY].val) {
insert_detailed_para_history(ip->next, ip->next->next, alpha,
pos_vec, pos_vec_size);
}
Stats[CL_GENERATED]++;
Stats[PARA_FROM_GEN]++;
if (heat_is_on())
paramodulant->heat_level = from_parent->heat_level + 1;
CLOCK_STOP(PARA_FROM_TIME);
pre_process(paramodulant, 0, Sos);
CLOCK_START(PARA_FROM_TIME);
}
}
else {
r = t->occ.rel;
while (r != NULL) {
if (r->clashable) {
r->path = 1; /* mark path from into_term up to atom */
para_from_up(r->argof, into_term, into_subst, alpha, from_subst);
r->path = 0; /* remove mark */
}
r = r->nocc;
}
}
} /* para_from_up */
/*************
*
* para_from_alpha(alpha)
*
* We are paramodulating from the given clause. This routine
* paramodulates from an alpha.
*
*************/
static void para_from_alpha(struct term *alpha)
{
struct context *into_subst, *from_subst;
struct term *into_term;
struct fpa_tree *ut;
struct trail *tr;
into_subst = get_context();
into_subst->multiplier = 0;
if(Flags[LAMBDA_FLAG].val) // Beeson 8.11.03
{ struct clause *ccl = getContainingClause(alpha); // Beeson 8.11.03
from_subst = get_context2(ccl,1); // Beeson 8.11.03
} // Beeson 8.11.03
else // Beeson 8.11.03
from_subst = get_context();
from_subst->multiplier = 1;
if (alpha->type == VARIABLE && Flags[PARA_FROM_VARS].val == 0)
; /* do nothing */
else {
if (alpha->type == VARIABLE)
ut = build_for_all(Fpa_clash_terms); /* get all terms in index */
else
ut = build_tree(alpha, UNIFY, Parms[FPA_TERMS].val,
Fpa_clash_terms);
for(into_term = next_term(ut, 0);into_term;into_term = next_term(ut, 0))
{ // Beeson rewrote while-loop as for-loop, 7.29.05
tr = NULL;
if(Flags[LAMBDA_FLAG].val) // Beeson 8.10.03
{ if(into_term->sym_num == AP
// && into_term->farg->argval->type == VARIABLE && // commented out Beeson 3.24.06
// into_subst->terms[into_term->farg->argval->varnum] == NULL // commented out Beeson 3.24.06
)
continue; // Don't paramodulate into Ap(X,w) terms // or into Ap terms of any kind
prepare_context(into_term,into_subst, from_subst->next_var); // Beeson 8.10.03
}
if (unify(into_term, into_subst, alpha, from_subst, &tr)) {
para_from_up(into_term, into_term, into_subst, alpha, from_subst);
clear_subst_1(tr);
}
}
}
free_context(into_subst);
free_context(from_subst);
} /* para_from_alpha */
/*************
*
* para_from(giv_cl) -- binary paramodulation from the given clause
*
* Paramodulants are given to the routine pre_process.
*
*************/
void para_from(struct clause *giv_cl)
{
struct literal *from_lit;
struct term *atom;
CLOCK_START(PARA_FROM_TIME);
if (!Flags[PARA_FROM_UNITS_ONLY].val || unit_clause(giv_cl)) {
// Beeson rewrote while-loop as a for-loop 7.29.05
for(from_lit = giv_cl->first_lit;from_lit;from_lit = from_lit->next_lit)
{
atom = from_lit->atom;
if(!pos_eq_lit(from_lit))
continue;
if(Flags[LAMBDA_FLAG].val) // Beeson 7.28.05
{ // don't paramodulate from a literal with an Ap term on either side
// whose first arg is a variable
struct term *alpha = atom->farg->argval;
if(alpha->sym_num == AP && alpha->farg->argval->type == VARIABLE)
continue; // don't paramodulate from Ap(X,..)
alpha = atom->farg->narg->argval;
if(alpha->sym_num == AP && alpha->farg->argval->type == VARIABLE)
continue; // don't paramodulate from Ap(X,..)
}
if (!term_ident(atom->farg->argval, atom->farg->narg->argval))
{ if (Flags[PARA_FROM_LEFT].val)
para_from_alpha(atom->farg->argval);
if (Flags[PARA_FROM_RIGHT].val)
para_from_alpha(atom->farg->narg->argval);
}
}
}
CLOCK_STOP(PARA_FROM_TIME);
} /* para_from */
/*************
*
* para_into_terms(t, into_lit, from_subst, into_subst)
*
* We are paramodulating into the given clause. This routine recursively
* goes through the clashable subterms of the given literal.
*
*************/
/* Beeson changed the from_subst parameter to a double pointer,
so that from_subst can be freed and re-allocated in this function,
and the final free_subst from the calling function will free the
last-allocated from_subst. */
static void para_into_terms(struct term *into_term,
struct literal *into_lit,
struct context **from_subst, // Beeson 4.1.04
struct context *into_subst)
{
struct term *alpha;
struct trail *tr;
struct fpa_tree *ut;
struct clause *paramodulant;
struct rel *r;
struct int_ptr *ip;
int pos_vec[MAX_FS_TERM_DEPTH];
int pos_vec_size;
int save_next_var=0, oldflag=0; // Beeson 6.30.05
int block_subterms = 0;
if (into_term->type == COMPLEX) {
if(Flags[LAMBDA_FLAG].val && Flags[INDUCTION_FLAG].val &&
blocking_functor(into_term->sym_num) // Beeson 7.1.05
)
block_subterms = 1; // don't paramodulate into Skolem terms during inductive proofs
if(Flags[LAMBDA_FLAG].val && into_term->sym_num == AP && // Beeson 7.29.05
into_term->farg->argval->type == VARIABLE && // Beeson 7.29.05
into_subst->terms[into_term->farg->argval->varnum] == NULL // Beeson 7.29.05
)
return; // don't paramodulate into Ap(X,w) or any subterms! // Beeson 7.29.05
r = into_term->farg;
if(! block_subterms) //Beeson 12.5.05
{ while (r != NULL)
{ if (r->clashable)
{ r->path = 1; /* mark path to into term */
para_into_terms(r->argval, into_lit, from_subst, into_subst);
r->path = 0; /* remove mark */
}
r = r->narg;
}
}
}
/* no need to check if variable and `no para into vars' */
/* because the clashability flag handles it */
#ifdef DIAGNOSTICS
fprintf(stdout, "Attempting paramodulation into:\n "); // DEBUG
print_term_nl(stdout,into_term); // DEBUG
#endif
if (into_term->type == VARIABLE)
ut = build_for_all(Fpa_alphas); /* get all terms in index */
else
ut = build_tree(into_term, UNIFY, Parms[FPA_TERMS].val, Fpa_alphas);
if(Flags[LAMBDA_FLAG].val) // Beeson 7.5.05
{ oldflag = Flags[LAMBDA_FLAG].val; // Beeson 6.30.05
Flags[LAMBDA_FLAG].val = 2; // Beeson 6.30.05
}
for(alpha = next_term(ut, 0);alpha != NULL; alpha = next_term(ut,0))
{ tr = NULL;
if(Flags[LAMBDA_FLAG].val) // Beeson 8.10.03
{ struct clause *c; // Beeson 3.30.04
int m; // Beeson 3.30.04
if(alpha->sym_num==AP) // Beeson 7.1.05
{ if(alpha->farg->argval->type == VARIABLE)
continue; // don't paramodulate from Ap(X,..)
}
#ifdef DIAGNOSTICS
fprintf(stdout, "From: "); print_term_nl(stdout,alpha); // DEBUG
#endif
c = getContainingClause(alpha); // Beeson 3.30.04
m = (*from_subst)->multiplier; // Beeson 3.30.04
free_context(*from_subst); // Beeson 3.30.04
*from_subst = get_context2(c,m); // Beeson 3.30.04
(*from_subst)->next_var = max_vars(getContainingClause(into_term),alpha); // Beeson 8.14.03
save_next_var = into_subst->next_var; // Beeson 6.30.05
}
if (unify(into_term, into_subst, alpha, *from_subst, &tr)) {
paramodulant = build_bin_para(alpha, *from_subst, into_term,
into_lit, into_subst,
pos_vec, &pos_vec_size);
/* fill in derivation info */
ip = paramodulant->parents;
ip->i = PARA_INTO_RULE;
ip->next->i = into_lit->container->id;
ip->next->next->i = alpha->occ.rel->argof->occ.lit->container->id;
if (Flags[DETAILED_HISTORY].val) {
insert_detailed_para_history(ip->next->next, ip->next, alpha,
pos_vec, pos_vec_size);
}
clear_subst_1(tr);
Stats[CL_GENERATED]++;
Stats[PARA_INTO_GEN]++;
if (heat_is_on())
paramodulant->heat_level = into_lit->container->heat_level + 1;
CLOCK_STOP(PARA_INTO_TIME);
pre_process(paramodulant, 0, Sos);
CLOCK_START(PARA_INTO_TIME);
} // close if unify
}
if(Flags[LAMBDA_FLAG].val == 2) // Beeson 6.30.05
{ Flags[LAMBDA_FLAG].val = oldflag; // Beeson 6.30.05
into_subst->next_var = save_next_var; // Beeson 6.30.06
}
} /* para_into_terms */
/*************
*
* para_into(giv_cl) -- binary paramodulation into the given clause
*
* Paramodulants are given to the routine pre_process.
*
*************/
void para_into(struct clause *giv_cl)
{
struct literal *into_lit;
struct context *into_subst, *from_subst;
struct rel *r;
CLOCK_START(PARA_INTO_TIME);
if (!Flags[PARA_INTO_UNITS_ONLY].val || unit_clause(giv_cl)) {
/* Substitutions are allocated here instead of in */
/* para_into_terms to save procedure calls. */
if(Flags[LAMBDA_FLAG].val) // Beeson
{ into_subst = get_context2(giv_cl,0);
}
else
{ into_subst = get_context();
into_subst->multiplier = 0;
}
from_subst = get_context();
from_subst->multiplier = 1;
into_lit = giv_cl->first_lit;
while (into_lit != NULL) {
if (into_lit->atom->varnum != ANSWER) { /* if not answer literal */
for( r = into_lit->atom->farg; r; r=r->narg)
// Beeson rewrote while-loop as for-loop 7.29.05
{ struct term *alpha = r->argval;
if(alpha->sym_num == AP &&
alpha->farg->argval->type == VARIABLE &&
into_subst->terms[alpha->farg->argval->sym_num] == NULL
) // Beeson 7.29.05
continue; // don't paramodulate into Ap(X,..)
if (r->clashable) {
r->path = 1; /* mark path to into term */
para_into_terms(r->argval, into_lit, &from_subst, into_subst);
r->path = 0; /* remove mark */
}
}
}
into_lit = into_lit->next_lit;
}
free_context(into_subst);
free_context(from_subst);
}
CLOCK_STOP(PARA_INTO_TIME);
} /* para_into */
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists