ref: 4fba3e66dce0d167d2031a0d1f1f6f4571cbd981
dir: /misc.c/
#include <u.h>
#include <libc.h>
#include <bio.h>
#include "dat.h"
#include "fns.h"
static uvlong varnr = 0;
Term *
copyterm(Term *orig, uvlong *clausenr)
{
Term *new = gmalloc(sizeof(Term));
memcpy(new, orig, sizeof(Term));
new->next = nil;
new->children = nil;
if(clausenr)
new->clausenr = *clausenr;
else
new->clausenr = orig->clausenr;
if(orig->tag == CompoundTerm){
Term *child;
for(child = orig->children; child != nil; child = child->next)
new->children = appendterm(new->children, copyterm(child, clausenr));
}
return new;
}
uvlong
smallestvar(Term *t)
{
if(t == nil)
return varnr;
if(t->tag == VariableTerm)
return t->varnr;
if(t->tag == CompoundTerm){
Term *child;
uvlong min = varnr;
for(child = t->children; child != nil; child = child->next){
uvlong v = smallestvar(child);
if(v < min)
min = v;
}
return min;
}else
return varnr;
}
void
addvarnr(Term *t, uvlong offset)
{
if(t == nil)
return;
if(t->tag == VariableTerm){
t->varnr += offset;
if(t->varnr >= varnr)
varnr = t->varnr+1;
}
if(t->tag == CompoundTerm){
Term *child;
for(child = t->children; child != nil; child = child->next)
addvarnr(child, offset);
}
}
void
renameclausevars(Clause *c)
{
uvlong minhead = smallestvar(c->head);
uvlong minbody = smallestvar(c->body);
uvlong minvar = minhead < minbody ? minhead : minbody;
uvlong offset = varnr - minvar;
addvarnr(c->head, offset);
addvarnr(c->body, offset);
}
Term *
appendterm(Term *a, Term *b)
{
if(a == nil)
return b;
if(b == nil)
return a;
Term *tmp;
for(tmp = a; tmp->next != nil; tmp = tmp->next);
tmp->next = b;
return a;
}
int
termslength(Term *list)
{
int len;
for(len = 0; list != nil; len++, list = list->next);
return len;
}
Term *
mkterm(int tag)
{
Term *t = gmalloc(sizeof(Term));
t->tag = tag;
t->next = nil;
t->children = nil;
t->text = nil;
t->clausenr = 0;
t->inparens = 0;
t->varnr = 0;
return t;
}
Term *
mkatom(Rune *name)
{
Term *t = mkterm(AtomTerm);
t->text = name;
return t;
}
Term *
mkvariable(void)
{
Term *t = mkterm(VariableTerm);
t->varnr = varnr++;
return t;
}
Term *
mkcompound(Rune *name, int arity, Term *args)
{
Term *t = mkterm(CompoundTerm);
t->text = name;
t->arity = arity;
t->children = args;
return t;
}
Term *
mkfloat(double dval)
{
Term *t = mkterm(FloatTerm);
t->dval = dval;
return t;
}
Term *
mkinteger(vlong ival)
{
Term *t = mkterm(IntegerTerm);
t->ival = ival;
return t;
}
Term *
mkstring(Rune *text)
{
Term *t = nil;
Rune *r;
switch(flagdoublequotes){
case DoubleQuotesChars:
for(r = text; *r != '\0'; r++){
Rune *chtext = runesmprint("%C", *r);
Term *ch = mkatom(chtext);
t = appendterm(t, ch);
}
t = mklist(t);
break;
case DoubleQuotesCodes:
for(r = text; *r != '\0'; r++){
Term *code = mkinteger(*r);
t = appendterm(t, code);
}
t = mklist(t);
break;
break;
case DoubleQuotesAtom:
t = mkatom(text);
}
return t;
}
Term *
mklist(Term *elems)
{
if(elems == nil)
return mkatom(L"[]");
else{
Term *t = copyterm(elems, nil);
t->next = mklist(elems->next);
return mkcompound(L".", 2, t);
}
}
Clause *
copyclause(Clause *orig, uvlong *clausenr)
{
Clause *new = gmalloc(sizeof(Clause));
new->head = copyterm(orig->head, clausenr);
if(orig->body)
new->body = copyterm(orig->body, clausenr);
else
new->body = nil;
if(clausenr)
new->clausenr = *clausenr;
else
new->clausenr = orig->clausenr;
new->next = nil;
return new;
}