ref: 13efe91101a11f41caf6321a8b2fbdd96ef9927a
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) { Term *new = gmalloc(sizeof(Term)); memcpy(new, orig, sizeof(Term)); new->next = nil; new->children = nil; if(orig->tag == CompoundTerm){ Term *child; for(child = orig->children; child != nil; child = child->next) new->children = appendterm(new->children, copyterm(child)); } 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 renametermvars(Term *t) { uvlong minvar = smallestvar(t); uvlong offset = varnr - minvar; addvarnr(t, 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->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); 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); if(orig->body) new->body = copyterm(orig->body); else new->body = nil; if(clausenr) new->clausenr = *clausenr; else new->clausenr = orig->clausenr; new->next = nil; return new; }