home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Vectronix 2
/
VECTRONIX2.iso
/
FILES_01
/
X_PROLOG.LZH
/
X_PROLOG
/
SOURCES
/
BIMETA.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-13
|
7KB
|
325 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 <ctype.h>
#include "prolog.h"
#include "extern.h"
#include "error.h"
extern functor *get_functor(); /* functor */
extern term *term_copy(); /* terms */
extern term *int_copy(); /* terms */
extern term *var_copy(); /* terms */
extern short term_unify(); /* terms */
extern term *term_instance(); /* terms */
extern term *argument(); /* terms */
extern void demolish_trails(); /* memory */
/* VAR ( term ) */
short bivar(args)
term *args[];
{
return(ISVAR(args[0]));
}
/* NONVAR ( term ) */
short binonvar(args)
term *args[];
{
return(! ISVAR(args[0]));
}
/* ATOM ( term ) */
short biatom(args)
term *args[];
{
return(ISATOM(args[0]));
}
/* INTEGER ( term ) */
short biinteger(args)
term *args[];
{
return(ISINT(args[0]));
}
/* ATOMIC ( term ) */
short biatomic(args)
term *args[];
{
return(ISATOM(args[0]) || ISINT(args[0]));
}
/* TRUE */
short bitrue( /* args */ )
/* term *args[]; */
{
return(TRUE);
}
/* FAIL */
short bifail( /* args */ )
/* term *args[]; */
{
return(FALSE);
}
/* FUNCTOR (term, functor, arity) */
short bifunctor(args)
term *args[];
{
term *t;
short i;
if (ISSTRUCT(args[0])) /* term */
{
if (ISVAR(args[1])) /* functor */
{
BIND_VAR(args[1],term_copy(get_functor(NAME(args[0]),0)));
}
else
{
if (!ISATOM(args[1]))
BIERROR(EBAD);
if (strcmp(NAME(args[0]), NAME(args[1])))
return(FALSE);
}
if (ISVAR(args[2])) /* arity */
{
BIND_VAR(args[2],int_copy((long)ARITY(args[0])));
return(TRUE);
}
else
{
if (!ISINT(args[2]))
BIERROR(EBAD);
return(ARITY(args[0]) == VALUE(args[2]));
}
}
if (!ISVAR(args[0]))
BIERROR(EBAD);
if (!ISATOM(args[1]) || !ISINT(args[2]))
BIERROR(EBAD);
i = (short)VALUE(args[2]);
if (i<0 || i>MAXARGS)
return(FALSE);
t = term_copy(get_functor(NAME(args[1]), i));
while (i>0)
ARG(t,i--) = var_copy();
BIND_VAR(args[0], t);
return(TRUE);
}
/* ARG ( pos, structure, term ) */
short biarg(args)
term *args[];
{
short i;
register term *pos = args[0];
register term *str = args[1];
register term *ter = args[2];
if (!ISSTRUCT(str))
BIERROR(EBAD);
if (!ISINT(pos))
BIERROR(EBAD);
i = (short)VALUE(pos);
if (i<0 || i>ARITY(str))
return(FALSE);
return(term_unify(argument(str,Topenv,i), Topenv, ter, Topenv));
}
/* =.. (structure, list) */
short biuniv(args)
term *args[];
{
register term *l, *t;
short i, j;
if (ISVAR(args[0]) && ISVAR(args[1]))
BIERROR(EBAD);
if (ISVAR(args[0]))
{
l = t = args[1];
/* Count the arguments */
for (i=0;;i++)
{
t = argument(t, Topenv, 2);
if (!ISSTRUCT(t)) /* only , and [] */
return(FALSE);
if (FUNC(t) != DOTFUNCTOR) /* [] found */
break;
}
if (!ISSTRUCT(argument(l,Topenv,1))) /* check head */
return(FALSE);
t = term_copy(get_functor(NAME(argument(l,Topenv,1)), i));
for (j=1; j<=i; j++)
{
l = argument(l,Topenv, 2);
ARG(t,j) = term_instance(argument(l, Topenv, 1), Topenv);
}
BIND_VAR(args[0], t);
return(TRUE);
}
/* first arg is a structure, lets construct a list and match */
/* it with the second argument */
t = l = term_copy(DOTFUNCTOR);
ARG(t,1) = term_copy(get_functor(NAME(args[0]),0));
for (i=1,j=ARITY(args[0]); i<=j; i++)
{
ARG(l,2) = term_copy(DOTFUNCTOR);
l = ARG(l,2);
ARG(l,1) = term_instance(argument(args[0], Topenv,i),Topenv);
}
ARG(l,2) = NILATOM;
return(term_unify(t, Topenv, args[1], Topenv));
}
/* NAME ( atom, list ) */
short biname(args)
term *args[];
{
register term *t, *l;
char *c;
short i;
char name[MAXNAME];
if (ISVAR(args[0]) && ISVAR(args[1]))
BIERROR(EBAD);
if (ISVAR(args[1])) /* let's build the name's list */
{
c = NAME(args[0]);
t = l = term_copy(DOTFUNCTOR);
while (*c) /* while chars left */
{
ARG(l,1) = int_copy((long)(*c++));
if (*c)
{
ARG(l,2) = term_copy(DOTFUNCTOR);
l = ARG(l,2);
}
}
ARG(l,2) = NILATOM;
BIND_VAR(args[1], t);
return(TRUE);
}
/* Otherwise we must construct the atom from the list */
l = t = args[1];
for (i=0; FUNC(t) == DOTFUNCTOR; i++)
{
name[i] = (char)VALUE(argument(t,Topenv,1));
t = argument(t, Topenv, 2);
}
name[i] = '\0';
t = term_copy(get_functor(name, 0));
return(term_unify(args[0], Topenv, t, Topenv));
}
/* ! (the cut) */
short bicut( /* args */ )
/* term *args[]; */
{
env *e;
env *e1;
term *t;
short i,j;
e = Topenv;
while (e)
{
e = e->pre;
if (FUNC(e->current) == COMMAFUNCTOR)
t = ARG(e->current, 1);
else
t = e->current;
if (FUNC(t) != CALLFUNCTOR)
break;
e = e->pre; /* skip the $call */
if (FUNC(e->current) == COMMAFUNCTOR)
t = ARG(e->current, 1);
else
t = e->current;
if (FUNC(t) == COMMAFUNCTOR || FUNC(t) == SEMICOLONFUNCTOR)
continue;
break;
}
/**/ if (e != Preenv) debug();
if (e) /* we found a proper enviroment */
{
/* if enviroment is frozen, remove backlogs above env */
/* the cruch the stack : move Topenv ontop of Preenv */
/* this saves some stack, but if we ! in a ; or , Goal */
/* this extra space is not freed */
if ((long)e < (long)Backpoint)
{
while ((long)e < (long)Backpoint->pre)
Backpoint = Backpoint->pre;
Backpoint = Backpoint->pre;
/* e1 points to space above Preenv */
e1 = (env *)((long)Preenv + sizeof(env) +
Preenv->nvars*sizeof(term));
/* move Topenv ontop of Preenv (at the place of e1) */
if (Topenv != e1) /* Topenv already here ? */
{
e1->pre = Preenv;
e1->current = Topenv->current;
j = e1->nvars = Topenv->nvars;
/* move frame of Topenv ontop of e1 */
/* j and t are utmost necessary because */
/* e1 and Topenv might overlap */
e1->frame = (term *)(e1+1); /* frame behind e */
t = Topenv->frame; /* frame behind Topenv */
for (i=0; i<j; i++)
e1->frame[i] = t[i];
}
Topenv = e1;
stacktop = (char *)((long)e1 + sizeof(env) +
e1->nvars * sizeof(term));
demolish_trails(Backpoint->traillev);
}
}
/**/ if (e != Preenv) debug();
return(TRUE);
}