home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Vectronix 2
/
VECTRONIX2.iso
/
FILES_01
/
X_PROLOG.LZH
/
X_PROLOG
/
SOURCES
/
BIDATABA.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-13
|
10KB
|
454 lines
/*
* X PROLOG Vers. 2.0
*
*
* Written by : Andreas Toenne
* CS Dept. , IRB
* University of Dortmund, W-Germany
* <at@unido.uucp>
* <....!seismo!unido!at>
* <at@unido.bitnet>
*
* Copyright : This software is copyrighted by Andreas Toenne.
* Permission is granted hereby to copy the entire
* package including this copyright notice without fee.
*
*/
#include <stdio.h>
#include "prolog.h"
#include "error.h"
#include "extern.h"
extern term *term_proto(); /* terms */
extern term *term_copy(); /* terms */
extern term *int_proto(); /* terms */
extern term *int_copy(); /* terms */
extern term *var_proto(); /* terms */
extern term *argument(); /* terms */
extern term *deref(); /* terms */
extern short term_unify(); /* terms */
extern clause *make_clause(); /* memory */
extern void remove_clause(); /* memory */
extern void push_env(); /* memory */
extern void push_frame(); /* memory */
extern functor *get_functor(); /* functor */
extern short bicut(); /* bimeta */
term *prototype(); /* forward */
short nvars; /* variables count */
/* Primitive for asserting clauses. */
/* Given the head and body of the clause, make a unique prototype */
/* of them and insert them in the right clause list either at */
/* the first or last position. */
short assert(head, body, first)
term *head;
term *body;
short first;
{
register clause *c,*d;
term *h,*b;
if (FUNC(head)->cp && (ISBUILTIN((clause *)FUNC(head)->cp) ||
ISPROTECTED(FUNC(head))))
return(FALSE);
/* test, if we reconsult this clause */
if (lastconsult && FUNC(head)->cp && (long)FUNC(head)!=lastconsult)
{
lastconsult = (long)FUNC(head);/* don't reconsult next time */
c = (clause *)FUNC(head)->cp;
FUNC(head)->cp = NULL;
while(c)
{
d = c;
c = c->next;
remove_clause(d);
}
}
nvars = 0; /* no vars in lookup table */
h = prototype(head);
b = (body ? prototype(body) : term_proto(TRUEFUNCTOR));
if (c_errno) /* error in prototype */
return(FALSE);
c = make_clause(0, h, b, nvars);
if (!FUNC(h)->cp || first) /* insert as first */
{
c->next = (clause *)FUNC(h)->cp;
FUNC(h)->cp = (char *)c;
}
else
{
d = (clause *)FUNC(h)->cp;
while (d->next)
d = d->next;
c->next = d->next;
d->next = c;
}
return(TRUE);
}
/* Primitive for building unique term prototypes */
/* Uses the global variables l_table und nvars for manageing */
/* variables. */
term *prototype(t)
term *t;
{
register short i;
register term *p;
if (ISANONYMOUS(t))
{
p = var_proto(0);
p->flags |= ANOPROTO; /* special !! */
return(p);
}
if (ISINT(t)) /* int's are easy */
return(int_proto(VALUE(t)));
if (ISVAR(t)) /* more tricky */
{
for (i=0; i<nvars; i++)
if (l_table[i].t == t) /* var found */
return(var_proto(i));
if (++nvars == MAXVARS) /* to much vars */
BIERROR(ETOOMANY);
l_table[i].t = t; /* enter variable */
return(var_proto(i));
}
if (ISSTRUCT(t)) /* compound term */
{
p = term_proto(FUNC(t)); /* make term */
for (i=1; i<=ARITY(t); i++)/* and make arguments */
ARG(p,i) = prototype(argument(t,Topenv,i));
return(p);
}
/* what's this ? */
return(NILATOM);
}
/* ASSERTA ( term ) */
short biasserta(args)
term *args[];
{
term *head, *body;
if (FUNC(args[0]) == IFFUNCTOR)
{
head = argument(args[0],Topenv, 1);
body = argument(args[0],Topenv, 2);
if (!ISSTRUCT(head))
BIERROR(EBAD);
return(assert(head, body, TRUE));
}
if (!ISSTRUCT(args[0]))
BIERROR(EBAD);
return(assert(args[0], NULL, TRUE));
}
/* ASSERTZ ( term ) */
short biassertz(args)
term *args[];
{
term *head, *body;
if (FUNC(args[0]) == IFFUNCTOR)
{
head = argument(args[0],Topenv, 1);
body = argument(args[0],Topenv, 2);
if (!ISSTRUCT(head))
BIERROR(EBAD);
return(assert(head, body, FALSE));
}
if (!ISSTRUCT(args[0]))
BIERROR(EBAD);
return(assert(args[0], NULL, FALSE));
}
/* Primitive builtin for finding a matching clause */
short bidollarclause(args)
term *args[];
{
term *head, *body, *help;
long ttemp; /* temp trail space */
term *oldtop, *oldnext; /* old copystack values */
char *oldstack;
env *oldenv;
register clause *c; /* try */
head = args[0];
body = args[1];
help = args[2];
if (FUNC(head)->cp && (ISBUILTIN((clause *)FUNC(head)->cp)
|| ISHIDDEN(FUNC(head))))
{
bicut();
return(FALSE);
}
if (ISVAR(help)) /* first try */
{
if (!FUNC(head)->cp) /* head has no clauses */
{
bicut(); /* cut off backtrack log */
return(FALSE); /* this is !,fail. */
}
help->flags &= ~VAR;
help->flags |= INT; /* make a frame integer :-) */
REF(help) = (term *)FUNC(head)->cp;
}
c = (clause *)REF(help);
/* Build a temporary enviroment to unify head and body with a clause */
oldstack = stacktop;
oldenv = Topenv;
push_env(Topenv, 0L);
push_frame(Topenv, MAXVARS);
while (c) /* while more possibilities */
{
ttemp = trailtop;
oldnext = copynext;
oldtop = copytop; /* save stacks for undoing effects */
/* Note ! c->body is possibly only a variable */
if (term_unify(head, Preenv, c->head, Topenv) &&
term_unify(body,Preenv,deref(c->body,Topenv),Topenv))
{
Topenv = oldenv;
Preenv = Topenv->pre;
stacktop = oldstack;
REF(help) = (term *)c->next;
return(TRUE); /* return this one */
}
pop_trails(ttemp);
copynext = oldnext;
copytop = oldtop; /* undo effects of unify */
c = c->next; /* try next clause */
}
/* no more clauses found */
Topenv = oldenv;
Preenv = Topenv->pre;
stacktop = oldstack;
help->flags &= ~INT;
help->flags |= VAR;
REF(help) = FREEVAR;
bicut();
return(FALSE);
}
/* Primitive built in for finding all functors */
short bidollarfunctor(args)
term *args[];
{
term *name, *arity;
register term *help;
register functor *f;
long ttemp;
term *oldnext, *oldtop;
name = args[0];
arity = args[1];
help = args[2];
if (!ISVAR(name) && !ISATOM(name))
BIERROR(EBAD);
if (!ISVAR(arity) && !ISINT(arity))
BIERROR(EBAD);
if (ISVAR(help)) /* first try */
{
help->flags &= ~VAR;
help->flags |= INT;
REF(help) = (term *)0;
}
f = (functor *)VALUE(help); /* next functor for try */
if (!f) /* first try */
f = (functor *)functorsp;
ttemp = trailtop;
oldnext = copynext;
oldtop = copytop; /* save stack values on entry */
while (f < functornext) /* until last functor */
{
/* don't show hidden functors */
if (ISHIDDEN(f))
goto fail;
/* hand coded unify for speed */
if (ISVAR(name))
{
BIND_VAR(name, term_copy(get_functor(f->name,0)));
}
else
if (strcmp(NAME(name), f->name))
goto fail;
if (ISVAR(arity))
{
BIND_VAR(arity, int_copy((long)f->arity));
}
else
if (VALUE(arity) != f->arity)
goto fail;
/* success */
VALUE(help) = (long)((long)f+sizeof(functor)+strlen(f->name));
if (VALUE(help) & 0x1)
VALUE(help)++;
return(TRUE);
fail:
pop_trails(ttemp);
copytop = oldtop;
copynext = oldnext;
f = (functor *)((long)f+sizeof(functor)+strlen(f->name));
if ((long)f & 0x1)
f = (functor *)((long)f + 1);
}
/* no more functors */
bicut();
help->flags &= ~INT;
help->flags |= VAR;
REF(help) = FREEVAR; /* clear help */
return(FALSE);
}
/* retract( clause ) */
short biretract(args)
term *args[];
{
term *head, *body;
long ttemp; /* temp trail space */
term *oldtop, *oldnext; /* old copystack values */
char *oldstack;
env *oldenv;
register clause *c; /* try */
clause *x;
if (! ISSTRUCT(args[0]))
BIERROR(EBAD);
if (FUNC(args[0]) == IFFUNCTOR) /* head :- body */
{
head = argument(args[0], Topenv, 1);
body = argument(args[0], Topenv, 2);
}
else
{
head = deref(args[0], Topenv);
body = NULL;
}
if (FUNC(head)->cp && (ISBUILTIN((clause *)FUNC(head)->cp)
|| ISPROTECTED(FUNC(head))))
return(FALSE);
if ((c = (clause *)FUNC(head)->cp) == NULL) /* no clause ? */
return(FALSE);
/* Build a temporary enviroment to unify head and body with a clause */
oldstack = stacktop;
oldenv = Topenv;
push_env(Topenv, 0L);
push_frame(Topenv, MAXVARS);
x = c;
while (c) /* while more possibilities */
{
ttemp = trailtop;
oldnext = copynext;
oldtop = copytop; /* save stacks for undoing effects */
if ((body && term_unify(head, Preenv, c->head, Topenv) &&
term_unify(body,Preenv, c->body, Topenv)) ||
term_unify(head, Preenv, c->head, Topenv))
{
stacktop = oldstack;
Topenv = oldenv;
Preenv = Topenv->pre;
if (c == (clause *)FUNC(head)->cp)
{
FUNC(head)->cp = (char *)c->next;
remove_clause(c);
}
else
{
x->next = c->next;
remove_clause(c);
}
return(TRUE);
}
pop_trails(ttemp);
copynext = oldnext;
copytop = oldtop; /* undo effects of unify */
x = c;
c = c->next; /* try next clause */
}
/* no more clauses found */
stacktop = oldstack;
Topenv = oldenv;
Preenv = Topenv->pre;
return(FALSE);
}
/* ABOLISH ( name, arity ) */
short biabolish(args)
term *args[];
{
functor *f;
clause *c1,*c2;
if (!ISATOM(args[0]) || !ISINT(args[1]))
BIERROR(EBAD);
f = get_functor(NAME(args[0]), (short)VALUE(args[1]));
if (!f->cp)
return(FALSE);
if (ISPROTECTED(f))
return(FALSE);
c1 = (clause *)f->cp;
f->cp = NULL;
while (c1)
{
c2 = c1;
c1 = c1->next;
remove_clause(c2);
}
return(TRUE);
}
/* $RECONSULTING( true/false ) */
short bireconsulting(args)
term *args[];
{
if (!ISINT(args[0]))
BIERROR(EBAD);
lastconsult = VALUE(args[0]);
return(TRUE);
}