Sindbad~EG File Manager
/*
* lrpo.c -- Lexicograpphic recursive path ordering (RPO with status)
*
*/
#include "header.h"
/*************
*
* int sym_precedence(sym_num_1, sym_num_2)
*
* Return SAME_AS, GREATER_THAN, LESS_THAN, or NOT_COMPARABLE.
*
*************/
static int sym_precedence(int sym_num_1,
int sym_num_2)
{
int p1, p2, sn;
static int warning_given;
if (sym_num_1 == sym_num_2)
return(SAME_AS);
else {
p1 = sn_to_node(sym_num_1)->lex_val;
p2 = sn_to_node(sym_num_2)->lex_val;
if (p1 == MAX_INT || p2 == MAX_INT) {
if (!warning_given) {
sn = (p1 == MAX_INT ? sym_num_1 : sym_num_2);
fprintf(stderr, "%c\nWARNING: at least one symbol, %s, is not lexically comparable.\nIf you use a lex command, you should include all symbols that\nwill be compared. This warning will not be given again.\n", Bell, sn_to_str(sn));
warning_given = 1;
}
return(NOT_COMPARABLE);
}
else if (p1 > p2)
return(GREATER_THAN);
else if (p1 < p2)
return(LESS_THAN);
else
return(SAME_AS);
}
} /* sym_precedence */
/*************
*
* int lrpo_status(sym_num)
*
*************/
static int lrpo_status(int sym_num)
{
return(sn_to_node(sym_num)->lex_rpo_status);
} /* lrpo_status */
/*************
*
* int lrpo_lex(t1, t2) -- Is t1 > t2 ?
*
* t1 and t2 have same functor and the functor has lr status.
* (If a functor really has rl status, its args have already been
* reversed. This is true of all subterms of t1 and t2.)
*
*************/
static int lrpo_lex(struct term *t1,
struct term *t2)
{
struct rel *r1, *r2;
int rc;
/* First skip over any identical arguments. */
/* (Same number of args, because same functor.) */
for (r1 = t1->farg, r2 = t2->farg;
r1 && term_ident(r1->argval, r2->argval);
r1 = r1->narg, r2 = r2->narg) /* empty body */ ;
if (!r1)
rc = 0; /* t1 and t2 identical */
else if (lrpo(r1->argval, r2->argval)) {
/* return (t1 > each remaining arg of t2) */
for (r2 = r2->narg; r2 && lrpo(t1, r2->argval); r2 = r2->narg)
/* empty body */ ;
rc = (r2 == NULL);
}
else {
/* return (there is a remaining arg of t1 s.t. arg == t2 or arg > t2) */
rc = 0;
for (r1 = r1->narg; r1; r1 = r1->narg) {
if (term_ident(r1->argval, t2) || lrpo(r1->argval, t2))
rc = 1;
}
}
return(rc);
} /* lrpo_lex */
/*************
*
* int num_occurrences(t_arg, t) -- How many times does t_arg occur
* as an argument of t?
*
*************/
static int num_occurrences(struct term *t_arg,
struct term *t)
{
struct rel *r;
int i;
for (i = 0, r = t->farg; r; r = r->narg)
if (term_ident(r->argval, t_arg))
i++;
return(i);
} /* num_occurrences */
/*************
*
* struct term *set_multiset_diff(t1, t2)
*
* Construct the multiset difference, then return the set of that.
* Result must be deallocated by caller with zap_term.
*
* In other words, viewing a term as a multiset of its arguments,
* find the set of t1's arguments that have more occurrences in
* t1 than in t2.
*
*************/
static struct term *set_multiset_diff(struct term *t1,
struct term *t2)
{
struct term *t_result;
struct rel *prev, *curr, *r1, *r;
int i;
t_result = get_term();
prev = NULL;
i = 0;
for (r1 = t1->farg; r1; r1 = r1->narg) {
/* First check if a preceeding occurrence of this arg has */
/* already been done. */
for (r = t1->farg; r != r1 && term_ident(r->argval, r1->argval) == 0; r = r->narg)
/* empty body */ ;
if (r == r1 && num_occurrences(r1->argval, t1) > num_occurrences(r1->argval, t2)) {
i++;
curr = get_rel();
curr->argval = copy_term(r1->argval);
if (!prev)
t_result->farg = curr;
else
prev->narg = curr;
prev = curr;
}
}
t_result->type = (i == 0 ? NAME : COMPLEX) ;
/* note that no sym_num is assigned; this should be ok */
return(t_result);
} /* set_multiset_diff */
/*************
*
* int lrpo_multiset(t1, t2) -- Is t1 > t2 in the lrpo multiset ordering?
*
* t1 and t2 have functors with the same precedence.
*
* let n(a,t) be the number of occurrences of a (as an argument) in t.
*
* t1 >(multiset) t2 iff for each arg a2 of t2 with n(a2,t2) > n(a2,t1),
* there is an arg a1 of t1 such that n(a1,t1) > n(a1,t2), and a1>a2.
*
*************/
static int lrpo_multiset(struct term *t1,
struct term *t2)
{
struct term *s1, *s2;
struct rel *r1, *r2;
int ok;
s1 = set_multiset_diff(t1, t2); /* builds and returns a set */
s2 = set_multiset_diff(t2, t1); /* builds and returns a set */
/*
* return (s2 not empty and foreach arg a2 of s2
* there is an arg a1 of s1 such that lrpo(a1, a2)).
*/
if (s2->farg == NULL)
ok = 0;
else {
for (r2 = s2->farg, ok = 1; r2 && ok; r2 = r2->narg) {
for (r1 = s1->farg, ok = 0; r1 && !ok ; r1 = r1->narg)
ok = lrpo(r1->argval, r2->argval);
}
}
zap_term(s1);
zap_term(s2);
return(ok);
} /* lrpo_multiset */
/*************
*
* int lrpo(t1, t2) - Is t1 > t2 in the lexicographic recursive
* path ordering?
*
*************/
int lrpo(struct term *t1,
struct term *t2)
{
int p;
struct rel *r;
if (t1->type == VARIABLE)
/* varaiable never greater than anything */
return(0);
else if (t2->type == VARIABLE)
/* t1 > variable iff t1 properly contains that variable */
return(occurs_in(t2, t1));
else if (t1->sym_num == t2->sym_num &&
lrpo_status(t1->sym_num) == LRPO_LR_STATUS)
return(lrpo_lex(t1, t2));
else {
p = sym_precedence(t1->sym_num, t2->sym_num);
if (p == SAME_AS)
return(lrpo_multiset(t1,t2));
else if (p == GREATER_THAN) {
/* return (t1 > each arg of t2) */
for (r = t2->farg; r && lrpo(t1, r->argval); r = r->narg)
/* empty body */ ;
return(r == NULL);
}
else { /* LESS_THEN or NOT_COMPARABLE */
/* return (there is an arg of t1 s.t. arg == t2 or arg > t2) */
for (r = t1->farg; r; r = r->narg) {
if (term_ident(r->argval, t2) || lrpo(r->argval, t2))
return(1);
}
return(0);
}
}
} /* lrpo */
/*************
*
* int lrpo_greater(t1, t2) - Is t1 > t2 in the lexicographic
* recursive path ordering?
*
* Time this routine.
*
*************/
int lrpo_greater(struct term *t1,
struct term *t2)
{
int rc;
#if 0
CLOCK_START(LRPO_TIME);
rc = lrpo(t1,t2);
CLOCK_STOP(LRPO_TIME);
#else
rc = lrpo(t1,t2);
#endif
return(rc);
} /* lrpo_greater */
/*************
*
* order_equalities_lrpo(c)
*
* For each equality literal (pos or neg), flip args if the right
* side is heavier. After possible filp, if the left side is
* heavier, set the ORIENTED_EQ_BIT in the atom.
* If the atom is flipped, set SCRATCH_BIT.
*
*************/
void order_equalities_lrpo(struct clause *c)
{
struct rel *r1, *r2;
struct term *alpha, *beta;
struct literal *l;
for (l = c->first_lit; l; l = l->next_lit) {
if (eq_lit(l)) {
r1 = l->atom->farg;
r2 = r1->narg;
alpha = r1->argval;
beta = r2->argval;
if (lrpo_greater(alpha, beta))
SET_BIT(l->atom->bits, ORIENTED_EQ_BIT);
else if (lrpo_greater(beta, alpha)) {
r1->argval = beta;
r2->argval = alpha;
SET_BIT(l->atom->bits, SCRATCH_BIT);
SET_BIT(l->atom->bits, ORIENTED_EQ_BIT);
}
}
}
} /* order_equalities_lrpo */
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists