home *** CD-ROM | disk | FTP | other *** search
- /*
-
- * 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);
-
- }
-
-