297 lines
5.9 KiB
C
297 lines
5.9 KiB
C
|
|
||
|
/* 2012 (C) Jussi Rintanen */
|
||
|
|
||
|
/* Symboltable for IDs and VARs in lexer */
|
||
|
|
||
|
#include "asyntax.h"
|
||
|
#include "tables.h"
|
||
|
#include "main.h"
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <assert.h>
|
||
|
|
||
|
#define noASSERTS
|
||
|
|
||
|
int maxSymbols;
|
||
|
int nOfSymbols;
|
||
|
|
||
|
void initsymboltable() {
|
||
|
int i;
|
||
|
|
||
|
maxSymbols = 50000;
|
||
|
nOfSymbols = 0;
|
||
|
for(i=0;i<MAXBUCKETS;i++) {
|
||
|
symboltable[i].index = -1;
|
||
|
symboltable[i].s = "";
|
||
|
symboltable[i].next = NULL;
|
||
|
}
|
||
|
|
||
|
index2stentry = (stentry **)statmalloc(50,maxSymbols * sizeof(stentry *));
|
||
|
}
|
||
|
|
||
|
/* Hash function for strings (PDDL symbols) */
|
||
|
|
||
|
int symbolhash(char *s) {
|
||
|
int hash,c,shift;
|
||
|
hash = 0;
|
||
|
while(*s != 0) {
|
||
|
c = (*s)-48;
|
||
|
hash = (hash << 5)-hash+c;
|
||
|
s += 1;
|
||
|
}
|
||
|
return hash&(MAXBUCKETS-1);
|
||
|
}
|
||
|
|
||
|
/* Return the index of a symbol. Either the symbol is already
|
||
|
in the symbol table with a given index, or it will be added
|
||
|
and assigne the next available non-negative integer. */
|
||
|
|
||
|
int symbolindex(char *s) {
|
||
|
int tmp;
|
||
|
char *ns;
|
||
|
stentry *ste;
|
||
|
|
||
|
tmp = symbolhash(s);
|
||
|
ste = symboltable+tmp;
|
||
|
|
||
|
// printf("Lookup: %s with hash %i.\n",s,symbolhash(s));
|
||
|
|
||
|
/* Search through all symbols in the bucket. */
|
||
|
|
||
|
while(ste->next != NULL && strcmp(s,ste->s) != 0) ste = ste->next;
|
||
|
|
||
|
/* Found one that matches: return its index. */
|
||
|
|
||
|
if(strcmp(s,ste->s) == 0) return ste->index;
|
||
|
|
||
|
/* New symbol. */
|
||
|
|
||
|
ns = (char *)statmalloc(51,strlen(s)+1); /* Make a new copy of the string */
|
||
|
strcpy(ns,s);
|
||
|
|
||
|
if(ste->index == -1) {
|
||
|
ste->s = ns;
|
||
|
ste->index = nOfSymbols++;
|
||
|
ste->staticpredicate = 1;
|
||
|
} else {
|
||
|
// printf("Hash collision\n");
|
||
|
// printf("[%i/%i]\n",tmp,nOfSymbols);
|
||
|
ste->next = (stentry *)statmalloc(52,sizeof(stentry));
|
||
|
ste->next->s = ns;
|
||
|
ste->next->index = nOfSymbols++;
|
||
|
ste->next->staticpredicate = 1;
|
||
|
ste->next->next = NULL;
|
||
|
ste = ste->next;
|
||
|
}
|
||
|
|
||
|
// printf("New entry %i with has %i is %s\n",nOfSymbols-1,symbolhash(s),ns);
|
||
|
|
||
|
if(nOfSymbols >= maxSymbols) {
|
||
|
maxSymbols = maxSymbols * 2;
|
||
|
index2stentry = (stentry **)realloc(index2stentry,maxSymbols * sizeof(stentry *));
|
||
|
}
|
||
|
|
||
|
index2stentry[nOfSymbols-1] = ste;
|
||
|
|
||
|
return ste->index;
|
||
|
|
||
|
}
|
||
|
|
||
|
char *symbol(int i) {
|
||
|
switch(i) {
|
||
|
case -1: return "PARAM-0";
|
||
|
case -2: return "PARAM-1";
|
||
|
case -3: return "PARAM-2";
|
||
|
case -4: return "PARAM-3";
|
||
|
case -5: return "PARAM-4";
|
||
|
case -6: return "PARAM-5";
|
||
|
case -7: return "PARAM-6";
|
||
|
case -8: return "PARAM-7";
|
||
|
case -9: return "PARAM-8";
|
||
|
case -10: return "PARAM-9";
|
||
|
default:
|
||
|
if(i<0) return "PARAMn";
|
||
|
else {
|
||
|
// printf("entry %i is %s\n",i,index2stentry[i]->s);
|
||
|
return index2stentry[i]->s;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void setnonstatic(int i) {
|
||
|
index2stentry[i]->staticpredicate = 0;
|
||
|
}
|
||
|
|
||
|
int isvar(int i) {
|
||
|
char *s;
|
||
|
s = index2stentry[i]->s;
|
||
|
return (*s == '?');
|
||
|
}
|
||
|
|
||
|
/* Symboltable for p(o1,...,on) atoms. */
|
||
|
|
||
|
#define ATABLESIZE 0x10000
|
||
|
#define MAXARITY 100
|
||
|
|
||
|
typedef struct _atomhashelement{ /* Mapping from atoms to indices */
|
||
|
int index;
|
||
|
intlist *a;
|
||
|
struct _atomhashelement *tl;
|
||
|
} atomhashelement;
|
||
|
|
||
|
atomhashelement *atomhash[ATABLESIZE]; /* Mapping from atoms to indices */
|
||
|
|
||
|
intlist **atomtable; /* Mapping from indices to atoms (lists of strings) */
|
||
|
int maxAtoms;
|
||
|
|
||
|
void initatomtable() {
|
||
|
int i;
|
||
|
|
||
|
nOfAtoms = 0;
|
||
|
maxAtoms = 50000;
|
||
|
|
||
|
atomtable = (intlist **)statmalloc(53,sizeof(intlist *) * maxAtoms);
|
||
|
|
||
|
for(i=0;i<ATABLESIZE;i++) atomhash[i] = NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* What is the index of the variable in action's parameter list? */
|
||
|
|
||
|
//int bindingindex(int i,typedvarlist *p) {
|
||
|
// int j;
|
||
|
// j = 0;
|
||
|
// while(p->v != i) {
|
||
|
// p = p->tl;
|
||
|
// j += 1;
|
||
|
// assert(p != NULL);
|
||
|
// }
|
||
|
// return j;
|
||
|
//}
|
||
|
|
||
|
/* silly auxiliary function */
|
||
|
|
||
|
int sameatom(int *i,intlist *j) {
|
||
|
while(j != NULL) {
|
||
|
if(*i != j->hd) return 0;
|
||
|
i+=1;
|
||
|
j = j->tl;
|
||
|
}
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int bvalue(int i,int *b) {
|
||
|
if(i<0) {
|
||
|
return b[-1-i];
|
||
|
} else {
|
||
|
return i; /* If not variable, it is already an object. */
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Fetch the index of an atom from the hash table, or create new. */
|
||
|
|
||
|
int atomindex(atom a,int *b) {
|
||
|
atomhashelement *l,*ol;
|
||
|
int hash,n,i,j;
|
||
|
int syms[MAXARITY+1]; /* vector of symbols in the atom */
|
||
|
|
||
|
/* Compute a hash number for the atom */
|
||
|
syms[0] = a[0];
|
||
|
hash = a[0];
|
||
|
j=1;
|
||
|
for(i=2;i<2+a[1];i++) {
|
||
|
/* Fetch from the current assignment */
|
||
|
n = bvalue(a[i],b);
|
||
|
hash = (hash << 5)^n;
|
||
|
#ifdef ASSERTS
|
||
|
assert(j < MAXARITY);
|
||
|
#endif
|
||
|
syms[j] = n;
|
||
|
j += 1;
|
||
|
}
|
||
|
|
||
|
hash = hash & (ATABLESIZE-1);
|
||
|
|
||
|
l = atomhash[hash];
|
||
|
|
||
|
ol = NULL;
|
||
|
|
||
|
while(l != NULL) {
|
||
|
/* printf("%i %i %i*\n",hash,(int)(l->tl),(int)(l->a)); */
|
||
|
if(sameatom(syms,l->a)) return l->index;
|
||
|
ol = l;
|
||
|
l = l->tl;
|
||
|
}
|
||
|
|
||
|
/* Was not in the list, create new. */
|
||
|
|
||
|
l = (atomhashelement *)statmalloc(54,sizeof(atomhashelement));
|
||
|
|
||
|
if(ol == NULL) {
|
||
|
atomhash[hash] = l;
|
||
|
} else {
|
||
|
ol->tl = l;
|
||
|
}
|
||
|
|
||
|
l->index = nOfAtoms;
|
||
|
l->a = NULL;
|
||
|
l->tl = NULL;
|
||
|
|
||
|
for(i=j-1;i>=0;i--) {
|
||
|
l->a = intcons(syms[i],l->a);
|
||
|
/* if(l->a == 1 && l->tl == 1) { printf("BINGO!!!\n"); exit(1); } */
|
||
|
}
|
||
|
|
||
|
nOfAtoms += 1;
|
||
|
|
||
|
if(nOfAtoms >= maxAtoms) {
|
||
|
maxAtoms = maxAtoms * 3 / 2;
|
||
|
atomtable = (intlist **)realloc(atomtable,maxAtoms * sizeof(intlist *));
|
||
|
}
|
||
|
|
||
|
atomtable[nOfAtoms-1] = l->a;
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
printf("CREATED ATOM %i:",l->index); printatomi(l->index); printf("\n");
|
||
|
#endif
|
||
|
|
||
|
return l->index;
|
||
|
|
||
|
}
|
||
|
|
||
|
int printatomi(int i) {
|
||
|
int len;
|
||
|
intlist *a = atomtable[i];
|
||
|
|
||
|
assert(i >= 0);
|
||
|
assert(i < nOfAtoms);
|
||
|
|
||
|
if(a == NULL) {
|
||
|
fprintf(stderr,"INTERNAL ERROR: symbol table 1244\n");
|
||
|
assert(1==0);
|
||
|
}
|
||
|
printf("%s(",symbol(a->hd));
|
||
|
len = 1+strlen(symbol(a->hd));
|
||
|
a = a->tl;
|
||
|
while(a != NULL) {
|
||
|
#ifdef ASSERTS
|
||
|
assert(a->hd >= 0);
|
||
|
#endif
|
||
|
printf("%s",symbol(a->hd));
|
||
|
len += strlen(symbol(a->hd));
|
||
|
if(a->tl != NULL) { printf(","); len += 1; }
|
||
|
a = a->tl;
|
||
|
}
|
||
|
printf(")"); len += 1;
|
||
|
return len;
|
||
|
}
|
||
|
|
||
|
void renameatomtable(int nOfAtoms,int *mapping) {
|
||
|
int i;
|
||
|
for(i=0;i<nOfAtoms;i++) {
|
||
|
if(mapping[i] != -1) atomtable[mapping[i]] = atomtable[i];
|
||
|
}
|
||
|
}
|