Initial commit with Madagascar 2016-01-22
This commit is contained in:
commit
21571c20a1
109
Cground.c
Normal file
109
Cground.c
Normal file
@ -0,0 +1,109 @@
|
||||
|
||||
cfma Cgroundfma(Sfma *,int *);
|
||||
|
||||
void Cgroundfmalist(Sfmalist *fs,int *ptr,int *b) {
|
||||
while(fs != NULL) {
|
||||
*(ptr++) = Cgroundfma(fs->hd,b);
|
||||
fs = fs->tl;
|
||||
}
|
||||
}
|
||||
|
||||
cfma Cgroundfma(Sfma *sf,int *b) {
|
||||
int *vals;
|
||||
int i,cnt;
|
||||
Sfmalist *fs;
|
||||
cfma f;
|
||||
|
||||
switch(Sfmatypeof(sf)) {
|
||||
|
||||
case STRUE: return cTRUE;
|
||||
case SFALSE: return cFALSE;
|
||||
|
||||
case Sconj:
|
||||
f = (cfma)malloc(sizeof(int *) * (sf->cnt + 1));
|
||||
Cgroundfmalist(sf->juncts,f+1,b);
|
||||
f[0] = 1+(sf->cnt << 1);
|
||||
return f;
|
||||
|
||||
case Sdisj:
|
||||
f = (cfma)malloc(sizeof(int *) * (sf->cnt + 1));
|
||||
Cgroundfmalist(sf->juncts,f+1,b);
|
||||
f[0] = (sf->cnt << 1);
|
||||
return f;
|
||||
|
||||
case Seq:
|
||||
if(bvalue(sf->p1,b) == bvalue(sf->p2,b)) {
|
||||
return cTRUE;
|
||||
} else {
|
||||
return cFALSE;
|
||||
}
|
||||
|
||||
case Sneq:
|
||||
if(bvalue(sf->p1,b) == bvalue(sf->p2,b)) {
|
||||
return cFALSE;
|
||||
} else {
|
||||
return cTRUE;
|
||||
}
|
||||
|
||||
case Spatom: return cPATOM(atomindex(sf->a,b));
|
||||
|
||||
case Snatom: return cNATOM(atomindex(sf->a,b));
|
||||
|
||||
case Sforall: /* Iterate over all values of the variable. */
|
||||
|
||||
cnt = getdomainsize(sf->ss->t);
|
||||
|
||||
f = (cfma)malloc(sizeof(int *) * (cnt + 1));
|
||||
|
||||
f[0] = (cnt << 1) + 1;
|
||||
|
||||
vals = getdomain(sf->ss->t);
|
||||
|
||||
for(i=0;i<cnt;i++) {
|
||||
b[-1-sf->ss->v] = vals[i];
|
||||
f[i+1] = Cgroundfma(sf->f,b);
|
||||
}
|
||||
|
||||
return f;
|
||||
|
||||
case Sforsome: /* Iterate over all values of the variable. */
|
||||
|
||||
cnt = getdomainsize(sf->ss->t);
|
||||
|
||||
f = (cfma)malloc(sizeof(int *) * (cnt + 1));
|
||||
|
||||
f[0] = (cnt << 1);
|
||||
|
||||
vals = getdomain(sf->ss->t);
|
||||
|
||||
for(i=0;i<cnt;i++) {
|
||||
b[-1-sf->ss->v] = vals[i];
|
||||
f[i+1] = Cgroundfma(sf->f,b);
|
||||
}
|
||||
|
||||
return f;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void printcfma(cfma f) {
|
||||
int i;
|
||||
if(((int)f)&1) { /* Atom */
|
||||
switch(((int)f)&7) {
|
||||
case cTRUEtag: printf("TRUE"); break;
|
||||
case cFALSEtag: printf("FALSE"); break;
|
||||
case cPATOMtag: printatomi((((int)f) >> 3)); break;
|
||||
case cNATOMtag: printf("NOT "); printatomi((((int)f) >> 3)); break;
|
||||
}
|
||||
} else {
|
||||
int cnt;
|
||||
if(((int)(*f))&1) printf("(AND"); else printf("(OR");
|
||||
cnt = ((int)(*f)) >> 1;
|
||||
for(i=0;i<cnt;i++) {
|
||||
printf(" ");
|
||||
printcfma(f[i+1]);
|
||||
}
|
||||
printf(")");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
74
Makefile
Normal file
74
Makefile
Normal file
@ -0,0 +1,74 @@
|
||||
# 2012 (C) Jussi Rintanen, jrintanen.jr@gmail.com
|
||||
|
||||
# Uncomment for Madagascar with the planning heuristic as default (Mp)
|
||||
#VERSION = -DMPDOWNLOAD
|
||||
#EXECUTABLE=Mp
|
||||
# Uncomment for Madagascar C with the planning heuristic as default (MpC)
|
||||
VERSION = -DCMPDOWNLOAD
|
||||
EXECUTABLE=MpC
|
||||
# Uncomment for Madagascar with VSIDS as default (M)
|
||||
#VERSION = -DVSIDS
|
||||
#EXECUTABLE=M
|
||||
#ARCH=-m32
|
||||
|
||||
INSTRUMENT = #-g -ggdb -pg
|
||||
|
||||
CONFIGURATION= -DLBD -DREPRTHREE -DWEIGHTS #-DFUIP #-DMULTICORE #-DSPREAD -DCOSTS -DCFMA -DCP3
|
||||
|
||||
#FEATURES= -fopenmp
|
||||
#LINKFEATURES= -fopenmp
|
||||
|
||||
# The following options are specific to GCC. Disable when necessary (e.g. in OS X).
|
||||
GCCOPTIMIZE= $(ARCH) -O3 -fprefetch-loop-arrays -funroll-loops -ftree-loop-im -ftracer -maccumulate-outgoing-args -momit-leaf-frame-pointer #-falign-functions=64
|
||||
|
||||
CFLAGS = $(VERSION) $(FEATURES) $(CONFIGURATION) $(INSTRUMENT) $(GCCOPTIMIZE) -w #-Wall
|
||||
|
||||
PARSERGENERATOR=bison
|
||||
PARSERC = parser.tab.c
|
||||
PARSERH = parser.tab.h
|
||||
PARSER=parser
|
||||
#PARSERGENERATOR=yacc
|
||||
#PARSERC = y.tab.c
|
||||
#PARSERH = y.tab.h
|
||||
#PARSER=y
|
||||
|
||||
CC = gcc
|
||||
|
||||
#LINKFLAGS = -L . -lcp3 -lpthread -lz -lrt #-static
|
||||
#LINKFLAGS = -s
|
||||
LINKFLAGS = $(ARCH) -static
|
||||
|
||||
OBJ = $(PARSER).tab.o main.o asyntax.o lex.yy.o tables.o operators.o invariants.o intsets.o cleanup.o translate2sat.o scc.o clausesets.o printplan.o clausedb.o dimacsinput.o ground.o
|
||||
HDR = main.h asyntax.h tables.h operators.h invariants.h intsets.h cleanup.h scc.h intsets.h translate2sat.h ordintsets.h clausedb.h interface.h printplan.h dimacsinput.h
|
||||
|
||||
all: nplan
|
||||
|
||||
nplan: date lex.yy.c Makefile $(PARSERC) $(OBJ) $(HDR)
|
||||
$(CC) $(LINKFLAGS) $(LINKFEATURES) $(INSTRUMENT) $(OBJ) -lm -o $(EXECUTABLE)
|
||||
|
||||
clausesets.o: heuristics2.c varvals.c learn2.c
|
||||
|
||||
ground.o: Cground.c
|
||||
|
||||
%.o: %.c Makefile $(HDR)
|
||||
$(CC) $(CFLAGS) $(AMD64FLAGS) -c $<
|
||||
|
||||
date:
|
||||
./makedate
|
||||
|
||||
main.o: zPRINTDATE
|
||||
|
||||
$(PARSERC): parser.y
|
||||
$(PARSERGENERATOR) -d parser.y
|
||||
|
||||
$(PARSERH): parser.y
|
||||
$(PARSERGENERATOR) -d parser.y
|
||||
|
||||
lex.yy.c: lexer.lex $(PARSERH) $(PARSERH)
|
||||
flex lexer.lex
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) $(PARSERC) $(PARSERH)
|
||||
|
||||
tar:
|
||||
tar cvf MADAGASCAR.TAR README plan build asyntax.c asyntax.h clausedb.c clausedb.h clausesets.c clausesets.h cleanup.c cleanup.h dimacs.h dimacsinput.c dimacsinput.h ground.c Cground.c heuristics2.c interface.h intsets.c intsets.h invariants.c invariants.h lexer.lex main.c main.h makedate Makefile operators.c operators.h ordintsets.c ordintsets.h parser.y printplan.c printplan.h scc.c scc.h tables.c tables.h translate2sat.c translate2sat.h varvals.c learn2.c shortcuts.c zPOSTF zPREF
|
17
README
Normal file
17
README
Normal file
@ -0,0 +1,17 @@
|
||||
|
||||
2010, 2011, 2012, 2013, 2014, 2015 (C) Jussi Rintanen
|
||||
|
||||
|
||||
Compilation:
|
||||
Choose between M, Mp and MpC by commenting/uncommenting the lines for
|
||||
VERSION and EXECUTABLE in Makefile
|
||||
make
|
||||
|
||||
The command line for the executables consist of a number of options and
|
||||
the names of input file names. With an empty command line you get the list
|
||||
of options together with information on the default configuration.
|
||||
|
||||
MpC often consumes all available memory, so it is critical to make sure that
|
||||
-m N flag is set sensibly. Too high values lead to paging, and too low values
|
||||
may mean that plans are not found. The default can be adjusted in main.c as
|
||||
the default value of the flagMemoryLimit variable.
|
784
asyntax.c
Normal file
784
asyntax.c
Normal file
@ -0,0 +1,784 @@
|
||||
|
||||
/* 2012 (C) Jussi Rintanen */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "asyntax.h"
|
||||
#include "tables.h"
|
||||
#include "intsets.h"
|
||||
#include "ordintsets.h"
|
||||
#include "operators.h"
|
||||
#include "main.h"
|
||||
|
||||
#define noDEBUG 1
|
||||
|
||||
#include "parser.tab.h"
|
||||
|
||||
//void printlitarr(int *ptr) {
|
||||
// if(*ptr == -1) { printf("NOTHING TO PRINT"); }
|
||||
// while(*ptr != -1) {
|
||||
// if((*ptr)&1) printf("NOT "); else printf(".");
|
||||
// printatomi((*ptr) >> 1);
|
||||
// ptr ++;
|
||||
// }
|
||||
// printf("\n");
|
||||
//}
|
||||
|
||||
/* DESTRUCTIVE negation of a formula */
|
||||
|
||||
Sfma *Sneg(Sfma *f) {
|
||||
Sfmalist *l;
|
||||
switch(f->t) {
|
||||
case STRUE: f->t = SFALSE; break;
|
||||
case SFALSE: f->t = STRUE; break;
|
||||
case Spatom: f->t = Snatom; break;
|
||||
case Snatom: f->t = Spatom; break;
|
||||
case Sconj:
|
||||
f->t = Sdisj;
|
||||
l = f->juncts;
|
||||
while(l != NULL) {
|
||||
Sneg(l->hd);
|
||||
l = l->tl;
|
||||
}
|
||||
break;
|
||||
case Sdisj:
|
||||
f->t = Sconj;
|
||||
l = f->juncts;
|
||||
while(l != NULL) {
|
||||
Sneg(l->hd);
|
||||
l = l->tl;
|
||||
}
|
||||
break;
|
||||
case Sforall: f->t = Sforsome; Sneg(f->f); break;
|
||||
case Sforsome: f->t = Sforall; Sneg(f->f); break;
|
||||
case Seq: f->t = Sneq; break;
|
||||
case Sneq: f->t = Seq; break;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
/* constructors for schematic formulae */
|
||||
|
||||
Sfma* Sdisjunction(Sfmalist *fs) {
|
||||
Sfma *f = (Sfma*)statmalloc(20,sizeof(Sfma));
|
||||
f->t = Sdisj;
|
||||
f->juncts = fs;
|
||||
return f;
|
||||
}
|
||||
|
||||
Sfma* Sconjunction(Sfmalist *fs) {
|
||||
Sfma *f = (Sfma*)statmalloc(21,sizeof(Sfma));
|
||||
f->t = Sconj;
|
||||
f->juncts = fs;
|
||||
return f;
|
||||
}
|
||||
|
||||
Sfma* Satom(atom a) {
|
||||
Sfma *f = (Sfma*)statmalloc(22,sizeof(Sfma));
|
||||
f->t = Spatom;
|
||||
f->a = a;
|
||||
return f;
|
||||
}
|
||||
|
||||
Sfma* Sfalse() {
|
||||
Sfma *f = (Sfma*)statmalloc(23,sizeof(Sfma));
|
||||
f->t = SFALSE;
|
||||
return f;
|
||||
}
|
||||
|
||||
Sfma* Strue() {
|
||||
Sfma *f = (Sfma*)statmalloc(24,sizeof(Sfma));
|
||||
f->t = STRUE;
|
||||
return f;
|
||||
}
|
||||
|
||||
Sfma* Sfmaforall(typedvarlist *ss, Sfma *f) {
|
||||
Sfma *f1 = (Sfma*)statmalloc(25,sizeof(Sfma));
|
||||
f1->t = Sforall;
|
||||
f1->ss = ss;
|
||||
f1->f = f;
|
||||
return f1;
|
||||
}
|
||||
|
||||
Sfma* SconstantTRUE() {
|
||||
Sfma *f = (Sfma*)statmalloc(26,sizeof(Sfma));
|
||||
f->t = STRUE;
|
||||
return f;
|
||||
}
|
||||
|
||||
Sfma* Sfmaforsome(typedvarlist *ss, Sfma *f) {
|
||||
Sfma *f1 = (Sfma*)statmalloc(27,sizeof(Sfma));
|
||||
f1->t = Sforsome;
|
||||
f1->ss = ss;
|
||||
f1->f = f;
|
||||
return f1;
|
||||
}
|
||||
|
||||
Sfma* SfmaEQ(int p1, int p2) {
|
||||
Sfma *f1 = (Sfma*)statmalloc(28,sizeof(Sfma));
|
||||
f1->t = Seq;
|
||||
f1->p1 = p1;
|
||||
f1->p2 = p2;
|
||||
return f1;
|
||||
}
|
||||
|
||||
/******* Accessors ********/
|
||||
|
||||
Sfmatype Sfmatypeof(Sfma *f) {
|
||||
return f->t;
|
||||
}
|
||||
|
||||
//atom *makeatom(int pr,intlist *pars) {
|
||||
// atom a = (atom)statmalloc(29,sizeof(atom));
|
||||
// a->pred = pr;
|
||||
// a->params = pars;
|
||||
// return a;
|
||||
//}
|
||||
|
||||
/* Printing */
|
||||
|
||||
void printSfmalist(Sfmalist *);
|
||||
void printSefflist(Sefflist *);
|
||||
|
||||
void printatom(atom a) {
|
||||
int n,i;
|
||||
printf("%s(",symbol(a[0]));
|
||||
n = a[1];
|
||||
for(i=2;i<n+2;i++) {
|
||||
if(a[i] < 0) printf("#%i",-1-(a[i]));
|
||||
else printf("%s",symbol(a[i]));
|
||||
if(i<n+1) printf(",");
|
||||
}
|
||||
printf(")");
|
||||
}
|
||||
|
||||
void printtypedvars(typedvarlist *ss) {
|
||||
printf(" (");
|
||||
while(ss != NULL) {
|
||||
printf("%s:%s",symbol(ss->v),symbol(ss->t));
|
||||
if(ss->tl != NULL) printf(" ");
|
||||
ss = ss->tl;
|
||||
}
|
||||
printf(")");
|
||||
}
|
||||
|
||||
void printSfma(Sfma *f) {
|
||||
switch(Sfmatypeof(f)) {
|
||||
case STRUE: printf("TRUE"); break;
|
||||
case SFALSE: printf("FALSE"); break;
|
||||
case Seq: printf(" (= %s %s)",symbol(f->p1),symbol(f->p2)); break;
|
||||
case Sneq: printf(" (not (= %s %s))",symbol(f->p1),symbol(f->p2)); break;
|
||||
case Spatom: printatom(f->a); break;
|
||||
case Snatom: printf("(not "); printatom(f->a); printf(")"); break;
|
||||
case Sdisj: printf("(or "); printSfmalist(f->juncts); printf(")"); break;
|
||||
case Sconj: printf("(and "); printSfmalist(f->juncts); printf(")"); break;
|
||||
case Sforall: printf("(forall "); printtypedvars(f->ss); printSfma(f->f); printf(")"); break;
|
||||
case Sforsome: printf("(exists "); printtypedvars(f->ss); printSfma(f->f); printf(")"); break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void printSfmalist(Sfmalist *fs) {
|
||||
while(fs != NULL) {
|
||||
printSfma(fs->hd);
|
||||
printf(" ");
|
||||
fs = fs->tl;
|
||||
}
|
||||
}
|
||||
|
||||
void printSeff(Seff *);
|
||||
void printSefflist(Sefflist *fs) {
|
||||
while(fs != NULL) {
|
||||
printSeff(fs->hd);
|
||||
printf(" ");
|
||||
fs = fs->tl;
|
||||
}
|
||||
}
|
||||
|
||||
void printSeff(Seff *e) {
|
||||
switch(e->t) {
|
||||
case SEpatom: printatom(e->a); break;
|
||||
case SEnatom: printf("(not "); printatom(e->a); printf(")"); break;
|
||||
case SEconj: printf("(and "); printSefflist(e->juncts); printf(")"); break;
|
||||
case SEforall: printf("(forall "); printtypedvars(e->ss); printSeff(e->effect); printf(")"); break;
|
||||
case SEwhen:
|
||||
printf("(when ");
|
||||
printSfma(e->cond);
|
||||
printf(" ");
|
||||
printSeff(e->effect);
|
||||
printf(")");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void printSaction(Saction *a) {
|
||||
typedvarlist *l;
|
||||
printf(":action %s(",symbol(a->name));
|
||||
l = a->params;
|
||||
while(l != NULL) {
|
||||
printf("%s",symbol(l->v));
|
||||
if(l->t) printf(":%s",symbol(l->t));
|
||||
else printf(":UNIV");
|
||||
if(l->tl != NULL) printf(" ");
|
||||
l = l->tl;
|
||||
}
|
||||
printf(") (COST %i)\n",a->cost);
|
||||
printSfma(a->precon);
|
||||
printf("\n");
|
||||
printSeff(a->effect);
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
/* constructors for schematic effects */
|
||||
|
||||
Seff* SPeffatom(atom a) {
|
||||
Seff *e = (Seff *)statmalloc(30,sizeof(Seff));
|
||||
e->t = SEpatom;
|
||||
e->a = a;
|
||||
return e;
|
||||
}
|
||||
|
||||
Seff* SNeffatom(atom a) {
|
||||
Seff *e = (Seff *)statmalloc(31,sizeof(Seff));
|
||||
e->t = SEnatom;
|
||||
e->a = a;
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
Seff* Seffconjunction(Sefflist *efs) {
|
||||
Seff *e = (Seff *)statmalloc(32,sizeof(Seff));
|
||||
e->t = SEconj;
|
||||
e->juncts = efs;
|
||||
return e;
|
||||
}
|
||||
|
||||
Seff* Seffwhen(Sfma *c,Seff *e) {
|
||||
Seff *e1 = (Seff *)statmalloc(33,sizeof(Seff));
|
||||
e1->t = SEwhen;
|
||||
e1->cond = c;
|
||||
e1->effect = e;
|
||||
return e1;
|
||||
}
|
||||
|
||||
Seff* Seffforall(typedvarlist *p,Seff *e) {
|
||||
Seff *e1 = (Seff *)statmalloc(34,sizeof(Seff));
|
||||
e1->t = SEforall;
|
||||
e1->ss = p;
|
||||
e1->effect = e;
|
||||
return e1;
|
||||
}
|
||||
|
||||
int listlen(intlist *l) {
|
||||
int len = 0;
|
||||
while(l != NULL) {
|
||||
len = len+1;
|
||||
l = l->tl;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Create atom */
|
||||
|
||||
atom newatom(int s,intlist *p) {
|
||||
int len,i;
|
||||
int *a;
|
||||
len = listlen(p);
|
||||
a = (atom)statmalloc(35,sizeof(int) * (len+2));
|
||||
a[0] = s;
|
||||
a[1] = len;
|
||||
i = 2;
|
||||
while(p != NULL) {
|
||||
a[i++] = p->hd;
|
||||
p = p->tl;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/* PDDL domain definitions */
|
||||
|
||||
int nOfTypes;
|
||||
|
||||
#define MAXOBTYPES 1000
|
||||
obtype Stypes[MAXOBTYPES];
|
||||
int *AStypes[MAXOBTYPES];
|
||||
int *AStypesCARD[MAXOBTYPES];
|
||||
|
||||
#define MAXSCHEMATICACTIONS 10000
|
||||
|
||||
Sfma *Sgoal;
|
||||
|
||||
void initPDDL() {
|
||||
nOfSActions = 0;
|
||||
maxSActions = MAXSCHEMATICACTIONS;
|
||||
Sactions = (Saction *)statmalloc(36,sizeof(Saction) * maxSActions);
|
||||
nOfTypes = 0;
|
||||
Sgoal = (Sfma *)0;
|
||||
Sactions[0].precon = NULL;
|
||||
Sactions[0].effect = NULL;
|
||||
Sactions[0].params = NULL;
|
||||
Sactions[0].cost = 0.0;
|
||||
}
|
||||
|
||||
/* Definitions */
|
||||
|
||||
|
||||
/* Typed var lists */
|
||||
|
||||
typedvarlist *TVappend(typedvarlist *l1,typedvarlist *l2) {
|
||||
if(l1 == NULL) {
|
||||
return l2;
|
||||
} else {
|
||||
typedvarlist *l3 = TVappend(l1->tl,l2);
|
||||
typedvarlist *l4 = (typedvarlist *)statmalloc(37,sizeof(typedvarlist));
|
||||
l4->v = l1->v;
|
||||
l4->t = l1->t;
|
||||
l4->tl = l3;
|
||||
return l4;
|
||||
}
|
||||
}
|
||||
|
||||
/* For a (possibly untyped) list of variables, assign a type */
|
||||
|
||||
typedvarlist *withtype(int t,intlist *ss) {
|
||||
typedvarlist *l;
|
||||
if(ss == NULL) return NULL;
|
||||
l = (typedvarlist *)statmalloc(38,sizeof(typedvarlist));
|
||||
l->v = ss->hd;
|
||||
l->t = t;
|
||||
l->tl = withtype(t,ss->tl);
|
||||
return l;
|
||||
}
|
||||
|
||||
/* Add a new action */
|
||||
|
||||
void checkSactionsSize() {
|
||||
if(nOfSActions >= maxSActions-1) {
|
||||
maxSActions = maxSActions * 2;
|
||||
Sactions = (Saction *)realloc(Sactions,maxSActions * sizeof(Saction));
|
||||
assert(Sactions != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void addnewaction(int name) {
|
||||
nOfSActions += 1;
|
||||
checkSactionsSize();
|
||||
Sactions[nOfSActions-1].name = name;
|
||||
if(Sactions[nOfSActions-1].effect == NULL) {
|
||||
fprintf(stderr,"ERROR: action has not effect.\n");
|
||||
exit(1);
|
||||
}
|
||||
if(Sactions[nOfSActions-1].precon == NULL) {
|
||||
Sactions[nOfSActions-1].precon = SconstantTRUE();
|
||||
}
|
||||
/* Next action */
|
||||
Sactions[nOfSActions].precon = NULL;
|
||||
Sactions[nOfSActions].effect = NULL;
|
||||
Sactions[nOfSActions].params = NULL;
|
||||
Sactions[nOfSActions].cost = 0.0;
|
||||
}
|
||||
|
||||
/* The following three are called by the parser BEFORE addnewaction */
|
||||
|
||||
void addactionparameters(typedvarlist *params) {
|
||||
Sactions[nOfSActions].params = params;
|
||||
}
|
||||
|
||||
void addactionprecond(Sfma *p) {
|
||||
Sactions[nOfSActions].precon = p;
|
||||
}
|
||||
|
||||
void addactioncost(int cost) {
|
||||
// printf("Action cost %i.\n",cost);
|
||||
Sactions[nOfSActions].cost = cost;
|
||||
}
|
||||
|
||||
/* Go through the predicates in an action effect and mark non-static ones. */
|
||||
|
||||
void checkifstatic(Seff *e) {
|
||||
atom a;
|
||||
Sefflist *es;
|
||||
switch(e->t) {
|
||||
case SEpatom:
|
||||
case SEnatom:
|
||||
a = e->a;
|
||||
setnonstatic(a[0]);
|
||||
break;
|
||||
case SEconj:
|
||||
es = e->juncts;
|
||||
while(es != NULL) {
|
||||
checkifstatic(es->hd);
|
||||
es = es->tl;
|
||||
}
|
||||
break;
|
||||
case SEwhen:
|
||||
case SEforall:
|
||||
checkifstatic(e->effect); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void addactioneffect(Seff *e) {
|
||||
Sactions[nOfSActions].effect = e;
|
||||
checkifstatic(e);
|
||||
}
|
||||
|
||||
/* Requirements */
|
||||
|
||||
void checkrequirements(intlist *l) {
|
||||
while(l != NULL) {
|
||||
if(strcmp(symbol(l->hd),":strips") == 0) {
|
||||
} else if(strcmp(symbol(l->hd),":conditional-effects") == 0) {
|
||||
} else if(strcmp(symbol(l->hd),":adl") == 0) {
|
||||
} else if(strcmp(symbol(l->hd),":typing") == 0) {
|
||||
} else if(strcmp(symbol(l->hd),":equality") == 0) {
|
||||
} else if(strcmp(symbol(l->hd),":typing") == 0) {
|
||||
} else if(strcmp(symbol(l->hd),":conditional-effects") == 0) {
|
||||
} else if(strcmp(symbol(l->hd),":negative-preconditions") == 0) {
|
||||
} else if(strcmp(symbol(l->hd),":quantified-preconditions") == 0) {
|
||||
} else if(strcmp(symbol(l->hd),":action-costs") == 0) {
|
||||
} else {
|
||||
fprintf(stderr,"WARNING: unsupported :requirement %s\n",symbol(l->hd));
|
||||
}
|
||||
|
||||
if(strcmp(symbol(l->hd),":action-costs") == 0) {
|
||||
fprintf(stderr,"WARNING: will ignore action costs\n");
|
||||
}
|
||||
|
||||
l = l->tl;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handling types and objects */
|
||||
|
||||
int member(int i,intlist *l) {
|
||||
while(l != NULL) {
|
||||
if(l->hd == i) return 1;
|
||||
l = l->tl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Destructive addition of a non-duplicate element to a NON-EMPTY list */
|
||||
intlist *addtolist(int s,intlist *l) {
|
||||
if(member(s,l)) return l;
|
||||
return intcons(s,l);
|
||||
}
|
||||
|
||||
void addobject(int v,int t) {
|
||||
int i;
|
||||
i = 0;
|
||||
while(i<nOfTypes) {
|
||||
if(t == Stypes[i].typename) { /* Add to type */
|
||||
Stypes[i].elements = addtolist(v,Stypes[i].elements);
|
||||
return;
|
||||
}
|
||||
i+=1;
|
||||
}
|
||||
nOfTypes += 1;
|
||||
Stypes[nOfTypes-1].typename = t;
|
||||
Stypes[nOfTypes-1].elements = intcons(v,EMPTYLIST);
|
||||
Stypes[nOfTypes-1].subtypes = EMPTYLIST;
|
||||
Stypes[nOfTypes-1].supertypes = EMPTYLIST;
|
||||
assert(nOfTypes < MAXOBTYPES);
|
||||
}
|
||||
|
||||
/* Predicate definition */
|
||||
|
||||
void storepredicates() {
|
||||
/* We don't use the predicate definition for anything. */
|
||||
/* It could be used for some form of type-checking. */
|
||||
}
|
||||
|
||||
/* Constant definitions */
|
||||
|
||||
void storeconstants(typedvarlist *cs) { /* Note: Same as 'storeobjects'. */
|
||||
while(cs != NULL) {
|
||||
addobject(cs->v,UNIVTYPE);
|
||||
addobject(cs->v,cs->t);
|
||||
cs = cs->tl;
|
||||
}
|
||||
}
|
||||
|
||||
/* Type definitions */
|
||||
|
||||
void addsubtype(int t1,int t2) {
|
||||
int i;
|
||||
i = 0;
|
||||
while(i<nOfTypes) {
|
||||
if(Stypes[i].typename == t2) {
|
||||
Stypes[i].subtypes = addtolist(t1,Stypes[i].subtypes);
|
||||
return;
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
nOfTypes += 1;
|
||||
Stypes[i].typename = t2;
|
||||
Stypes[i].supertypes = EMPTYLIST;
|
||||
Stypes[i].elements = EMPTYLIST;
|
||||
Stypes[i].subtypes = intcons(t1,EMPTYLIST);
|
||||
}
|
||||
|
||||
void addsupertype(int t1,int t2) {
|
||||
int i;
|
||||
i = 0;
|
||||
while(i<nOfTypes) {
|
||||
if(Stypes[i].typename == t1) {
|
||||
Stypes[i].supertypes = addtolist(t2,Stypes[i].supertypes);
|
||||
return;
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
nOfTypes += 1;
|
||||
Stypes[i].typename = t1;
|
||||
Stypes[i].supertypes = intcons(t2,EMPTYLIST);
|
||||
Stypes[i].subtypes = EMPTYLIST;
|
||||
Stypes[i].elements = EMPTYLIST;
|
||||
}
|
||||
|
||||
void extendsubtyperelation(int t1,int t2) {
|
||||
addsubtype(t1,t2);
|
||||
addsupertype(t1,t2);
|
||||
}
|
||||
|
||||
void storetypes(typedvarlist *ts) {
|
||||
while(ts != NULL) {
|
||||
extendsubtyperelation(ts->v,ts->t);
|
||||
ts = ts->tl;
|
||||
}
|
||||
}
|
||||
|
||||
void processtypes() {
|
||||
int i;
|
||||
intlist *il,*il2;
|
||||
|
||||
/* Extend subtypes and supertypes to non-immediate ones. */
|
||||
for(i=0;i<nOfTypes;i++) {
|
||||
il = Stypes[i].subtypes;
|
||||
while(il != NULL) {
|
||||
il2 = Stypes[i].supertypes;
|
||||
while(il2 != NULL) {
|
||||
addsubtype(il->hd,il2->hd);
|
||||
addsupertype(il->hd,il2->hd);
|
||||
il2 = il2->tl;
|
||||
}
|
||||
il = il->tl;
|
||||
}
|
||||
}
|
||||
|
||||
if(flagShowInput) {
|
||||
for(i=0;i<nOfTypes;i++) {
|
||||
printf("TYPE %s:\n",symbol(Stypes[i].typename));
|
||||
printf(" ELEMENTS:");
|
||||
il = Stypes[i].elements;
|
||||
while(il != NULL) {
|
||||
printf(" %s",symbol(il->hd));
|
||||
il = il->tl;
|
||||
}
|
||||
printf("\n");
|
||||
printf(" SUBTYPES:");
|
||||
il = Stypes[i].subtypes;
|
||||
while(il != NULL) {
|
||||
printf(" %s",symbol(il->hd));
|
||||
il = il->tl;
|
||||
}
|
||||
printf("\n");
|
||||
printf(" SUPERTYPES:");
|
||||
il = Stypes[i].supertypes;
|
||||
while(il != NULL) {
|
||||
printf(" %s",symbol(il->hd));
|
||||
il = il->tl;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Add objects of a type to all its supertypes. */
|
||||
for(i=0;i<nOfTypes;i++) {
|
||||
il = Stypes[i].elements;
|
||||
while(il != NULL) {
|
||||
il2 = Stypes[i].supertypes;
|
||||
while(il2 != NULL) {
|
||||
addobject(il->hd,il2->hd);
|
||||
il2 = il2->tl;
|
||||
}
|
||||
il = il->tl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* PDDL problem definitions */
|
||||
|
||||
/* Add objects to a type. */
|
||||
|
||||
void storeobjects(typedvarlist *cs) {
|
||||
while(cs != NULL) {
|
||||
addobject(cs->v,UNIVTYPE);
|
||||
addobject(cs->v,cs->t);
|
||||
cs = cs->tl;
|
||||
}
|
||||
}
|
||||
|
||||
void storeinit(atomlist *a) {
|
||||
int cnt,i;
|
||||
cnt = listlen(a);
|
||||
Sinit = (atom *)malloc((cnt+1) * sizeof(atom));
|
||||
for(i=0;i<cnt;i++) {
|
||||
Sinit[i] = a->hd;
|
||||
a = a->tl;
|
||||
}
|
||||
Sinit[cnt] = NULL;
|
||||
}
|
||||
|
||||
void storegoal(Sfma *f) {
|
||||
Sgoal = f;
|
||||
}
|
||||
|
||||
/* Domain name */
|
||||
|
||||
int domain,problem;
|
||||
|
||||
void storedomain(int s) { domain = s; }
|
||||
void checkdomain(int s) {
|
||||
if(s != domain) {
|
||||
fprintf(stderr,"WARNING: problem domain '%s' does not match domain name '%s'\n",symbol(s),symbol(domain));
|
||||
}
|
||||
}
|
||||
char *domainname() { return symbol(domain); }
|
||||
|
||||
void addproblem(int s) { problem = s; }
|
||||
char *problemname() { return symbol(problem); }
|
||||
|
||||
/* Lists */
|
||||
|
||||
Sfmalist *Sfmacons(Sfma *h,Sfmalist *t) {
|
||||
Sfmalist *r = (Sfmalist *)statmalloc(39,sizeof(Sfmalist));
|
||||
r->hd = h;
|
||||
r->tl = t;
|
||||
return r;
|
||||
}
|
||||
|
||||
Sefflist *Seffcons(Seff *h,Sefflist *t) {
|
||||
Sefflist *r = (Sefflist *)statmalloc(40,sizeof(Sefflist));
|
||||
r->hd = h;
|
||||
r->tl = t;
|
||||
return r;
|
||||
}
|
||||
|
||||
intlist *intcons(int h,intlist *t) {
|
||||
intlist *r = (intlist *)statmalloc(41,sizeof(intlist));
|
||||
r->hd = h;
|
||||
r->tl = t;
|
||||
return r;
|
||||
}
|
||||
|
||||
ptrlist *ptrcons(int *h,ptrlist *t) {
|
||||
ptrlist *r = (ptrlist *)statmalloc(42,sizeof(ptrlist));
|
||||
r->hd = h;
|
||||
r->tl = t;
|
||||
return r;
|
||||
}
|
||||
|
||||
atomlist *atomcons(atom h,atomlist *t) {
|
||||
atomlist *r = (atomlist *)statmalloc(43,sizeof(atomlist));
|
||||
r->hd = h;
|
||||
r->tl = t;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Reading and processing an input file */
|
||||
|
||||
void showstatistics() {
|
||||
int i;
|
||||
printf("%3i action schemata\n",nOfSActions);
|
||||
for(i=0;i<nOfSActions;i++) {
|
||||
printSaction(&(Sactions[i]));
|
||||
}
|
||||
printf("%3i types\n",nOfTypes);
|
||||
for(i=0;i<nOfTypes;i++) {
|
||||
intlist *ss;
|
||||
printf("%s consists of",symbol(Stypes[i].typename));
|
||||
ss = Stypes[i].elements;
|
||||
while(ss != NULL) {
|
||||
printf(" %s",symbol(ss->hd));
|
||||
ss = ss->tl;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Turn object lists Stypes to object arrays AStypes. */
|
||||
|
||||
void constructtypearrays() {
|
||||
int i,*ptr,cnt;
|
||||
intlist *l;
|
||||
for(i=0;i<nOfTypes;i++) {
|
||||
cnt = listlen(Stypes[i].elements);
|
||||
AStypesCARD[i] = cnt;
|
||||
AStypes[i] = (int *)malloc((1+cnt) * sizeof(int));
|
||||
l = Stypes[i].elements;
|
||||
// printf("%s has elements ",symbol(Stypes[i].typename));
|
||||
ptr = AStypes[i];
|
||||
while(l != NULL) {
|
||||
*ptr = l->hd;
|
||||
// printf(" %s",symbol(*ptr));
|
||||
l = l->tl;
|
||||
ptr = ptr + 1;
|
||||
}
|
||||
// printf("\n");
|
||||
*ptr = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void readfile() {
|
||||
linenumber = 1;
|
||||
if(nOfInputFiles == 0) {
|
||||
printf("Reading from standard input\n");
|
||||
lexeropenstdin();
|
||||
} else {
|
||||
lexeropen(inputfiles[0]);
|
||||
}
|
||||
errorstring = "";
|
||||
initPDDL();
|
||||
initsymboltable();
|
||||
UNIVTYPE = symbolindex("***UNIVTYPE***");
|
||||
yyparse();
|
||||
processtypes();
|
||||
constructtypearrays();
|
||||
if(flagShowInput) showstatistics();
|
||||
}
|
||||
|
||||
void yyerror( char *s) {
|
||||
printf("%s; %s on line %i.\n",s,errorstring,linenumber);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
/********************* Bindings and domains ************************/
|
||||
/*******************************************************************/
|
||||
|
||||
/* elements associated with a type */
|
||||
|
||||
int *getdomain(int type) {
|
||||
int j;
|
||||
for(j=0;j<nOfTypes;j++) {
|
||||
if(Stypes[j].typename == type) return AStypes[j];
|
||||
}
|
||||
fprintf(stderr,"WARNING: type %s not defined\n",symbol(type));
|
||||
exit(1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int getdomainsize(int type) {
|
||||
int j;
|
||||
for(j=0;j<nOfTypes;j++) {
|
||||
if(Stypes[j].typename == type) return AStypesCARD[j];
|
||||
}
|
||||
fprintf(stderr,"WARNING: type %s not defined\n",symbol(type));
|
||||
exit(1);
|
||||
return 0;
|
||||
}
|
188
asyntax.h
Normal file
188
asyntax.h
Normal file
@ -0,0 +1,188 @@
|
||||
|
||||
|
||||
/* 2012 (C) Jussi Rintanen */
|
||||
|
||||
#define feNEG(a) ((a)^1)
|
||||
#define fePLIT(a) ((a) << 1)
|
||||
#define feNLIT(a) (feNEG(fePLIT(a)))
|
||||
#define feVAR(l) ((l) >> 1)
|
||||
|
||||
/* An atomic fact (or schema) P(t1 t2 t3 ... tn) */
|
||||
|
||||
typedef struct _intlist { int hd; struct _intlist *tl; } intlist;
|
||||
typedef struct _ptrlist { int *hd; struct _ptrlist *tl; } ptrlist;
|
||||
typedef struct _stringlist { char *hd; struct _stringlist *tl; } stringlist;
|
||||
typedef struct _typedvarlist { int v; int t; struct _typedvarlist *tl; } typedvarlist;
|
||||
|
||||
/* An atom is represented as an int vector.
|
||||
a[0] is the predicate
|
||||
a[1] is the number of parameters n
|
||||
a[2..n+2] are the parameters */
|
||||
|
||||
typedef int *atom;
|
||||
|
||||
/******************* Schematic formulae ******************/
|
||||
|
||||
/* Definition */
|
||||
|
||||
typedef enum {
|
||||
STRUE,SFALSE,
|
||||
Spatom, Snatom,
|
||||
Sconj, Sdisj,
|
||||
Sforall, Sforsome,
|
||||
Seq, Sneq } Sfmatype;
|
||||
|
||||
typedef struct _Sfma {
|
||||
Sfmatype t;
|
||||
union {
|
||||
atom a;
|
||||
typedvarlist *ss; /* parameters for quantification */
|
||||
int p1;
|
||||
struct _Sfmalist0 { struct _Sfma *hd; struct _Sfmalist0 *tl; } *juncts;
|
||||
};
|
||||
#ifdef CFMA
|
||||
int cnt;
|
||||
#endif
|
||||
int p2;
|
||||
struct _Sfma *f;
|
||||
} Sfma;
|
||||
|
||||
typedef struct _Sfmalist { Sfma *hd; struct _Sfmalist *tl; } Sfmalist;
|
||||
|
||||
/* Constructors formulas */
|
||||
|
||||
Sfma *Sfalse();
|
||||
Sfma *Strue();
|
||||
Sfma *Sconjunction(Sfmalist *);
|
||||
Sfma *Sdisjunction(Sfmalist *);
|
||||
Sfma *Satom(atom);
|
||||
Sfma *Sneg(Sfma *);
|
||||
Sfma *SfmaEQ(int,int);
|
||||
Sfma *Sfmaforall(typedvarlist *,Sfma *);
|
||||
Sfma *Sfmaforsome(typedvarlist *,Sfma *);
|
||||
|
||||
Sfma *Sgoal;
|
||||
|
||||
/* Accessors */
|
||||
|
||||
Sfmatype Sfmatypeof(Sfma *);
|
||||
|
||||
/******************** Schematic effects *********************/
|
||||
|
||||
typedef enum { SEpatom, SEnatom, SEwhen, SEconj, SEforall } Sefftype;
|
||||
|
||||
/* schematic effects */
|
||||
|
||||
typedef struct _Seff {
|
||||
Sefftype t;
|
||||
union {
|
||||
atom a;
|
||||
Sfma *cond; /* condition for when */
|
||||
struct _Sefflist0 { struct _Seff *hd; struct _Sefflist0 *tl; } *juncts; /* list of effects for conj */
|
||||
typedvarlist *ss; /* parameter in forall quantification */
|
||||
};
|
||||
struct _Seff *effect; /* effect for when, forall */
|
||||
} Seff;
|
||||
|
||||
/* Lists */
|
||||
|
||||
typedef struct _Sefflist { Seff *hd; struct _Sefflist* tl; } Sefflist;
|
||||
typedef struct _atomlist { atom hd; struct _atomlist* tl; } atomlist;
|
||||
|
||||
Sfmalist *Sfmacons(Sfma *,Sfmalist *);
|
||||
Sefflist *Seffcons(Seff *,Sefflist *);
|
||||
intlist *intcons(int,intlist *);
|
||||
atomlist *atomcons(atom,atomlist *);
|
||||
ptrlist *ptrcons(int *,ptrlist *);
|
||||
|
||||
#define EMPTYLIST NULL
|
||||
|
||||
/* Domain */
|
||||
|
||||
void storedomain(int);
|
||||
void checkdomain(int);
|
||||
char *domainname();
|
||||
|
||||
void storeconstants(typedvarlist *);
|
||||
void storetypes(typedvarlist *);
|
||||
void storepredicates();
|
||||
|
||||
void checkrequirements(intlist *);
|
||||
|
||||
|
||||
/* Problem */
|
||||
|
||||
void addproblem(int);
|
||||
char *problemname();
|
||||
|
||||
void storeinit(atomlist *);
|
||||
void storegoal(Sfma *);
|
||||
atom *Sinit;
|
||||
|
||||
/* Type variables */
|
||||
|
||||
int UNIVTYPE;
|
||||
typedvarlist *withtype(int,intlist *);
|
||||
typedvarlist *TVappend(typedvarlist *,typedvarlist *);
|
||||
|
||||
|
||||
/* An operator schema */
|
||||
|
||||
typedef struct _Saction {
|
||||
int name;
|
||||
typedvarlist *params;
|
||||
int cost;
|
||||
Sfma *precon;
|
||||
Seff *effect;
|
||||
} Saction;
|
||||
|
||||
int maxSActions;
|
||||
Saction *Sactions;
|
||||
int nOfSActions;
|
||||
void checkSactionsSize();
|
||||
|
||||
atom newatom(int,intlist *);
|
||||
|
||||
/* Types, with elements. */
|
||||
|
||||
typedef struct _obtype {
|
||||
int typename;
|
||||
intlist *elements;
|
||||
intlist *supertypes;
|
||||
intlist *subtypes;
|
||||
} obtype;
|
||||
|
||||
int *getdomain(int);
|
||||
int getdomainsize(int);
|
||||
void bindingaslist(int *,int *,int);
|
||||
|
||||
void storeobjects(typedvarlist *);
|
||||
|
||||
void showatom(atom);
|
||||
|
||||
int linenumber;
|
||||
char *errorstring;
|
||||
|
||||
void readfile();
|
||||
|
||||
/* Constructors */
|
||||
|
||||
/* schematic effects */
|
||||
Seff* Seffconjunction(Sefflist *);
|
||||
Seff* Seffwhen(Sfma*, Seff*);
|
||||
Seff* Seffforall(typedvarlist *,Seff *);
|
||||
Seff* SPeffatom(atom);
|
||||
Seff* SNeffatom(atom);
|
||||
|
||||
/* create new schematic op */
|
||||
void addnewaction(int);
|
||||
void addactionparameters(typedvarlist *);
|
||||
void addactionprecond(Sfma *);
|
||||
void addactioneffect(Seff *);
|
||||
void addactioncost(int);
|
||||
|
||||
/* Grounding */
|
||||
|
||||
void preprocessoperators();
|
||||
void groundoperators();
|
||||
void simplifysillyconditionals();
|
491
clausedb.c
Normal file
491
clausedb.c
Normal file
@ -0,0 +1,491 @@
|
||||
|
||||
/* 2012 (C) Jussi Rintanen, jrintanen.jr@gmail.com */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#include "interface.h"
|
||||
#include "clausedb.h"
|
||||
#include "clausesets.h"
|
||||
#include "printplan.h"
|
||||
#include "asyntax.h"
|
||||
#include "ordintsets.h"
|
||||
#include "operators.h"
|
||||
#include "translate2sat.h"
|
||||
|
||||
#define noDEBUG
|
||||
#define noASSERTS
|
||||
#define noALIGNMENT /* There is a problem: the padding is not handled by GC! */
|
||||
|
||||
typedef struct _clausedblist {
|
||||
int *block;
|
||||
int permanent;
|
||||
int blockptr;
|
||||
struct _clausedblist *nextblock;
|
||||
} clausedblist;
|
||||
|
||||
#if defined(__LP64__)
|
||||
#define BLOCKSIZE 1024*1024*8
|
||||
#else
|
||||
#define BLOCKSIZE 1024*1024*2
|
||||
#endif
|
||||
|
||||
clausedblist *cdb;
|
||||
int CDBclauses;
|
||||
|
||||
/* Given an int *, calculate the number of sizeof(int) to the
|
||||
next 64 byte alignment boundary. This is to align data structures
|
||||
with cache line boundaries.
|
||||
*/
|
||||
|
||||
int ptr2intpad(int *ptr) {
|
||||
int alignment = (((int)ptr)&63) >> 2;
|
||||
if(alignment) return 16-alignment;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
void check_malloc_success(void *ptr,int i) {
|
||||
if(ptr == NULL) {
|
||||
fprintf(stderr,"ERROR: Could not allocate more memory %i.\n",i);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clauses in the clause data base:
|
||||
location content
|
||||
-3 activity
|
||||
-2 SAT instance number
|
||||
-1 # of literals in clause
|
||||
0 1st literal
|
||||
1 2nd literal
|
||||
. .
|
||||
. .
|
||||
n-1 last literal
|
||||
n -1
|
||||
|
||||
WARNING: These should always be accessed with the indices PREFIX_xxxx
|
||||
defined in clausedb.h.
|
||||
|
||||
*/
|
||||
|
||||
void initclausedb() {
|
||||
cdb = (clausedblist *)malloc(sizeof(struct _clausedblist));
|
||||
check_malloc_success(cdb,1);
|
||||
|
||||
cdb->block = (int *)malloc(BLOCKSIZE*sizeof(int));
|
||||
check_malloc_success(cdb->block,2);
|
||||
|
||||
allocatedbyCDB = BLOCKSIZE*sizeof(int);
|
||||
|
||||
cdb->blockptr = 0;
|
||||
cdb->permanent = 1;
|
||||
cdb->nextblock = NULL;
|
||||
#ifdef DEBUG
|
||||
printf("FIRST CBD BLOCK %i\n",(int)cdb);
|
||||
#endif
|
||||
CDBclauses = 0;
|
||||
clausecount = 0;
|
||||
GCaggressiveness = 0; /* Remove only very old clauses. */
|
||||
}
|
||||
|
||||
|
||||
/* Update clause activity counter. The pointer is to the first literal. */
|
||||
|
||||
void updateactivity(int *c,int act) {
|
||||
c[PREFIX_ACTIVITY] = act;
|
||||
}
|
||||
|
||||
/* Set the LBD field of a clause. */
|
||||
|
||||
void setLBD(int *c,int lbd) {
|
||||
c[PREFIX_LBD] = lbd;
|
||||
}
|
||||
|
||||
|
||||
/* Allocate a clause. If permflag is 1, space allocated for
|
||||
the clause won't be freed or reused. */
|
||||
|
||||
int *allocc(int inst,int len,int permflag) {
|
||||
clausedblist *cls,*temp;
|
||||
int *ptr;
|
||||
#ifdef ALIGNMENT
|
||||
int alignment;
|
||||
#endif
|
||||
|
||||
#ifdef MULTICORE
|
||||
#pragma omp critical
|
||||
#endif
|
||||
{
|
||||
CDBclauses += 1;
|
||||
clausecount += 1;
|
||||
|
||||
cls = cdb;
|
||||
while(cls != NULL
|
||||
&& (cls->permanent != permflag
|
||||
|| cls->blockptr+len+PREFIXWORDS+5 > BLOCKSIZE))
|
||||
{
|
||||
cls = cls->nextblock;
|
||||
}
|
||||
|
||||
if(cls == NULL) { /* Allocate a new block. */
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("NEW CDB BLOCK (total of %i clauses now).\n",CDBclauses);
|
||||
#endif
|
||||
temp = cdb;
|
||||
|
||||
cdb = (clausedblist *)malloc(sizeof(struct _clausedblist));
|
||||
check_malloc_success(cdb,3);
|
||||
|
||||
cdb->block = (int *)malloc(BLOCKSIZE*sizeof(int));
|
||||
check_malloc_success(cdb->block,4);
|
||||
|
||||
allocatedbyCDB += BLOCKSIZE*sizeof(int);
|
||||
|
||||
cdb->permanent = permflag;
|
||||
cdb->nextblock = temp;
|
||||
cdb->blockptr = 0;
|
||||
|
||||
cls = cdb;
|
||||
|
||||
printf("\t\t\t\tAllocated %i MB %s(total %i MB)\n",
|
||||
BLOCKSIZE/1024/1024*sizeof(int),
|
||||
(permflag ? "permanent " : ""),
|
||||
(int)(memoryused()));
|
||||
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Allocating clause %i of length %i\n",cdb->blockptr,len);
|
||||
#endif
|
||||
|
||||
/* Allocate it from an existing block. */
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Allocating clause %i of length %i\n",cls->blockptr,len);
|
||||
#endif
|
||||
|
||||
/* Clauses should be aligned with cache line boundaries (16x4Bs?).
|
||||
Add something to cls->blockptr to make it align.
|
||||
*/
|
||||
|
||||
#ifdef ALIGNMENT
|
||||
cls->blockptr += ptr2intpad(&(cls->block[cls->blockptr]));
|
||||
#endif
|
||||
|
||||
ptr = &(cls->block[cls->blockptr+PREFIXWORDS]);
|
||||
}
|
||||
|
||||
cls->block[cls->blockptr+PREFIXWORDS+PREFIX_ACTIVITY] = 0;
|
||||
cls->block[cls->blockptr+PREFIXWORDS+PREFIX_LBD] = 0;
|
||||
cls->block[cls->blockptr+PREFIXWORDS+PREFIX_INSTANCE] = inst;
|
||||
cls->block[cls->blockptr+PREFIXWORDS+PREFIX_CLAUSELEN] = len;
|
||||
cls->block[cls->blockptr+len+PREFIXWORDS] = -1;
|
||||
cls->blockptr += len+1+PREFIXWORDS;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
/* Extract information from a clause pointed to by ptr (the first literal.) */
|
||||
|
||||
int clauselen(int *ptr) {
|
||||
return ptr[PREFIX_CLAUSELEN];
|
||||
}
|
||||
|
||||
|
||||
int SATinstance(int *ptr) {
|
||||
return ptr[PREFIX_INSTANCE];
|
||||
}
|
||||
|
||||
|
||||
/* Allocate space for a non-permanent clause. */
|
||||
|
||||
int *allocpermclause(int inst,int len) { return allocc(inst,len,1); }
|
||||
|
||||
int *allocclause(int inst,int len) { return allocc(inst,len,0); }
|
||||
|
||||
|
||||
/* The following has not been tested after the -2 and -3 fields were added. */
|
||||
|
||||
void showclauses(satinstance sati) {
|
||||
clausedblist *cls;
|
||||
int i,j,b;
|
||||
printf("All clauses in clause db:\n");
|
||||
|
||||
cls = cdb;
|
||||
b=0;
|
||||
while(cls != NULL) {
|
||||
i = 0;
|
||||
while(i < cls->blockptr) {
|
||||
printf("Clause at %i.%i:",b,i);
|
||||
for(j=i+PREFIXWORDS;j<i+PREFIXWORDS+(cls->block[i+PREFIXWORDS+PREFIX_CLAUSELEN]);j++) {
|
||||
printf(" [%i]:",cls->block[j]); printTlit(sati,cls->block[j]);
|
||||
}
|
||||
printf("\n");
|
||||
i = i+(cls->block[i+PREFIXWORDS+PREFIX_CLAUSELEN])+PREFIXWORDS+1;
|
||||
}
|
||||
cls = cls->nextblock;
|
||||
b += 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LBD
|
||||
int nofclausesinblock(clausedblist *block) {
|
||||
int n = 0;
|
||||
int i = 0;
|
||||
while(i < block->blockptr) {
|
||||
n++;
|
||||
i = i+(block->block[i+PREFIXWORDS+PREFIX_CLAUSELEN])+PREFIXWORDS+1;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
int nofnoninputclauses() {
|
||||
clausedblist *block = cdb;
|
||||
int n = 0;
|
||||
while(block) {
|
||||
if(block->permanent == 0) n += nofclausesinblock(block);
|
||||
block = block->nextblock;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
int intCmp0(int *a,int *b) {
|
||||
if(*a > *b) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
int medianLBD() {
|
||||
int n = nofnoninputclauses();
|
||||
{
|
||||
int i,j;
|
||||
int tmp[n];
|
||||
clausedblist *block = cdb;
|
||||
j = 0;
|
||||
while(block != NULL) {
|
||||
if(block->permanent == 0) {
|
||||
i = 0;
|
||||
while(i < block->blockptr) {
|
||||
tmp[j++] = block->block[i+PREFIXWORDS+PREFIX_LBD];
|
||||
i = i+(block->block[i+PREFIXWORDS+PREFIX_CLAUSELEN])+PREFIXWORDS+1;
|
||||
}
|
||||
}
|
||||
block = block->nextblock;
|
||||
}
|
||||
qsort(tmp,j,sizeof(int),intCmp0);
|
||||
return tmp[j >> 1];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
/*** Garbage collection: reclaim space used by useless clauses. ***/
|
||||
/***********************************************************************/
|
||||
|
||||
int uselessp(satinstance sati,int *c,int lbdbound) {
|
||||
int len,age,lbd;
|
||||
|
||||
len = c[PREFIXWORDS+PREFIX_CLAUSELEN];
|
||||
lbd = c[PREFIXWORDS+PREFIX_LBD];
|
||||
age = sati->conflicts - c[PREFIXWORDS+PREFIX_ACTIVITY];
|
||||
|
||||
if(len <= 5) return 0;
|
||||
|
||||
if(age > 200000) return 1;
|
||||
|
||||
if(lbd < lbdbound) return 0;
|
||||
|
||||
if(lbd == lbdbound && age < 500) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
PTRINT *nextwlelement(satinstance sati,int lit,int *ls) {
|
||||
if(ls[0] == lit) return &(ls[PREFIX_WATCHA]);
|
||||
else {
|
||||
#ifdef ASSERTS
|
||||
assert(ls[1] == lit);
|
||||
#endif
|
||||
return &(ls[PREFIX_WATCHB]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void findinlist(satinstance sati,int lit,int *c) {
|
||||
int *ls;
|
||||
|
||||
if(sati->value == 0) return; /* Instance is not used any more. */
|
||||
|
||||
ls = sati->lits[lit].watches;
|
||||
do {
|
||||
if(ls == c) {
|
||||
printf("Clause %ld found in the list of %i.\n",(PTRINT)c,lit);
|
||||
return;
|
||||
}
|
||||
|
||||
ls = *(nextwlelement(sati,lit,ls));
|
||||
} while(ls != NULL);
|
||||
printf("Clause not found!!!\n");
|
||||
}
|
||||
|
||||
|
||||
/* Remove a clause from the list of clauses in which a literal is watched. */
|
||||
|
||||
void removefromwlist(satinstance sati,int lit,int *c) {
|
||||
int *ls;
|
||||
int **prev;
|
||||
|
||||
if(sati->value == 0) return; /* Instance is not used any more. */
|
||||
|
||||
ls = sati->lits[lit].watches;
|
||||
prev = &(sati->lits[lit].watches);
|
||||
do {
|
||||
if(ls == c) {
|
||||
*prev = *(nextwlelement(sati,lit,ls));
|
||||
return;
|
||||
}
|
||||
prev = nextwlelement(sati,lit,ls);
|
||||
ls = *prev;
|
||||
#ifdef ASSERTS
|
||||
assert(ls != NULL);
|
||||
#endif
|
||||
} while(1==1);
|
||||
}
|
||||
|
||||
|
||||
/* Replace a clause by another one in the list of clauses. */
|
||||
|
||||
void replaceinwlist(satinstance sati,int lit,int *c1,int *c2) {
|
||||
int *ls;
|
||||
|
||||
if(sati->value == 0) return; /* Instance is not used any more. */
|
||||
|
||||
ls = sati->lits[lit].watches;
|
||||
|
||||
if(ls==c1) {
|
||||
sati->lits[lit].watches = c2;
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
if(ls[0] == lit) {
|
||||
if(c1 == lsACCESS_WATCHA) {
|
||||
lsASSIGN_WATCHA = c2;
|
||||
return;
|
||||
}
|
||||
ls = lsACCESS_WATCHA;
|
||||
} else {
|
||||
#ifdef ASSERTS
|
||||
assert(ls[1] == lit);
|
||||
#endif
|
||||
if(c1 == lsACCESS_WATCHB) {
|
||||
lsASSIGN_WATCHB = c2;
|
||||
return;
|
||||
}
|
||||
ls = lsACCESS_WATCHB;
|
||||
}
|
||||
#ifdef ASSERTS
|
||||
assert(ls != NULL);
|
||||
#endif
|
||||
} while(1==1);
|
||||
}
|
||||
|
||||
|
||||
/* Delete useless clauses and free the space used by them. */
|
||||
|
||||
int garbagecollection() {
|
||||
int i;
|
||||
int freed,inst;
|
||||
int ptr,fill,bytes;
|
||||
clausedblist *blocks;
|
||||
float freedMB;
|
||||
#ifdef LBD
|
||||
int lbdbound = medianLBD();
|
||||
#endif
|
||||
|
||||
#ifdef LBD
|
||||
/* printf("\t\t\t\t\t\tMedian LBD: %i\n",lbdbound); */
|
||||
#endif
|
||||
printf("\t\t\t\t\t\tGC:"); fflush(stdout);
|
||||
|
||||
freed = 0; /* Number of bytes freed. */
|
||||
|
||||
blocks = cdb;
|
||||
while(blocks != NULL) {
|
||||
|
||||
ptr = 0;
|
||||
|
||||
fill = 0; /* Where to move clauses when compacting. */
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Fill factor %i/%i (%.2f %, %.2f MB)",blocks->blockptr,BLOCKSIZE,((double)blocks->blockptr)*100.0/((double)BLOCKSIZE),((double)blocks->blockptr)*4.0/1024.0/1024.0);
|
||||
#endif
|
||||
|
||||
while(ptr < blocks->blockptr) {
|
||||
|
||||
inst = blocks->block[ptr+PREFIXWORDS+PREFIX_INSTANCE];
|
||||
|
||||
bytes = blocks->block[ptr+PREFIXWORDS+PREFIX_CLAUSELEN]+PREFIXWORDS+1;
|
||||
|
||||
/* Test integrity */
|
||||
// findinlist(seqs[inst].sati,
|
||||
// blocks->block[ptr+PREFIXWORDS],
|
||||
// &(blocks->block[ptr+PREFIXWORDS]));
|
||||
// findinlist(seqs[inst].sati,
|
||||
// blocks->block[ptr+PREFIXWORDS+1],
|
||||
// &(blocks->block[ptr+PREFIXWORDS]));
|
||||
|
||||
if((seqs[inst].sati->value == 0)
|
||||
|| (!blocks->permanent && (uselessp(seqs[inst].sati,blocks->block+ptr,lbdbound)))) { /* Useless clause? */
|
||||
removefromwlist(seqs[inst].sati,
|
||||
blocks->block[ptr+PREFIXWORDS],
|
||||
blocks->block+ptr+PREFIXWORDS);
|
||||
removefromwlist(seqs[inst].sati,
|
||||
blocks->block[ptr+PREFIXWORDS+1],
|
||||
blocks->block+ptr+PREFIXWORDS);
|
||||
freed += bytes;
|
||||
|
||||
} else { /* Otherwise shift it. */
|
||||
|
||||
if(fill < ptr) {
|
||||
replaceinwlist(seqs[inst].sati,
|
||||
blocks->block[ptr+PREFIXWORDS],
|
||||
blocks->block+ptr+PREFIXWORDS,
|
||||
blocks->block+fill+PREFIXWORDS);
|
||||
replaceinwlist(seqs[inst].sati,
|
||||
blocks->block[ptr+PREFIXWORDS+1],
|
||||
blocks->block+ptr+PREFIXWORDS,
|
||||
blocks->block+fill+PREFIXWORDS);
|
||||
|
||||
for(i=0;i<bytes;i++) blocks->block[fill+i] = blocks->block[ptr+i];
|
||||
}
|
||||
fill += bytes;
|
||||
}
|
||||
|
||||
ptr += bytes; /* Next clause */
|
||||
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf(" -> (%.2f %, %.2f MB).\n",
|
||||
((double)fill)*100/((double)BLOCKSIZE),
|
||||
((double)fill)*4.0/1024.0/1024.0);
|
||||
#endif
|
||||
|
||||
blocks->blockptr = fill;
|
||||
|
||||
blocks = blocks->nextblock;
|
||||
}
|
||||
|
||||
freedMB = ((float)freed) / (1024.0*256.0);
|
||||
printf(" %.2f MB\n",freedMB); fflush(stdout);
|
||||
|
||||
return (int)freedMB;
|
||||
}
|
91
clausedb.h
Normal file
91
clausedb.h
Normal file
@ -0,0 +1,91 @@
|
||||
|
||||
/* 2012 (C) Jussi Rintanen, jrintanen.jr@gmail.com */
|
||||
|
||||
float memoryused();
|
||||
void initclausedb(); /* This must be called once before adding any clauses. */
|
||||
int *allocpermclause(int,int);
|
||||
int *allocclause(int,int);
|
||||
int clauselen(int *);
|
||||
int SATinstance(int *);
|
||||
void showclauses(satinstance);
|
||||
void updateactivity(int *,int);
|
||||
void setLBD(int *,int);
|
||||
|
||||
void free_clauses(int);
|
||||
|
||||
int GCaggressiveness;
|
||||
double collectgarbage();
|
||||
|
||||
double allocatedbyCDB;
|
||||
|
||||
int clausecount;
|
||||
|
||||
void check_malloc_success(void *,int);
|
||||
|
||||
int ptr2intpad(int *); /* Calculate number of sizeof(int) to align. */
|
||||
|
||||
void falsifiedsomeclause(satinstance);
|
||||
|
||||
/* The pointers to the next clauses in which the watched literals occur
|
||||
are respectively either 4 or 8 bytes (1 or 2 sizeof(int)s), depending
|
||||
on whether we are in a 32 or 64 bit processor. This affects the indices
|
||||
of the different fields in the clause data structure. */
|
||||
|
||||
#if defined(__LP64__)
|
||||
#define PREFIXWORDS 8
|
||||
#else
|
||||
#define PREFIXWORDS 6
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if defined(__LP64__)
|
||||
#define PREFIX_WATCHA -8
|
||||
#define PREFIX_WATCHB -6
|
||||
#else
|
||||
#define PREFIX_WATCHA -6
|
||||
#define PREFIX_WATCHB -5
|
||||
#endif
|
||||
|
||||
|
||||
#define PREFIX_ACTIVITY -4
|
||||
#define PREFIX_LBD -3
|
||||
#define PREFIX_INSTANCE -2
|
||||
#define PREFIX_CLAUSELEN -1
|
||||
|
||||
/* Clauses in the clause data base:
|
||||
location content
|
||||
-6 watched literal watched clauses link 1
|
||||
-5 watched literal watched clauses link 2
|
||||
-4 activity
|
||||
-3 LBD
|
||||
-2 SAT instance number
|
||||
-1 # of literals in clause
|
||||
0 1st literal
|
||||
1 2nd literal
|
||||
. .
|
||||
. .
|
||||
n-1 last literal
|
||||
n -1
|
||||
|
||||
WARNING: These fields should always be accessed with the PREFIX_xxx macros.
|
||||
*/
|
||||
|
||||
/* Macros for accessing the pointers at c[PREFIX_WATCHA] and c[PREFIX_WATCHB].
|
||||
The issue is that c[] is an integer (4 byte) array, and in 64-bit
|
||||
architectures pointers are twice as long. */
|
||||
|
||||
|
||||
#define ASSIGN_WATCHA *((PTRINT *)(c+PREFIX_WATCHA))
|
||||
#define ACCESS_WATCHA *((PTRINT *)(c+PREFIX_WATCHA))
|
||||
#define ADDRESS_WATCHA ((PTRINT *)(c+PREFIX_WATCHA))
|
||||
|
||||
#define ASSIGN_WATCHB *((PTRINT *)(c+PREFIX_WATCHB))
|
||||
#define ACCESS_WATCHB *((PTRINT *)(c+PREFIX_WATCHB))
|
||||
#define ADDRESS_WATCHB ((PTRINT *)(c+PREFIX_WATCHB))
|
||||
|
||||
#define lsASSIGN_WATCHA *((PTRINT *)(ls+PREFIX_WATCHA))
|
||||
#define lsACCESS_WATCHA *((PTRINT *)(ls+PREFIX_WATCHA))
|
||||
|
||||
#define lsASSIGN_WATCHB *((PTRINT *)(ls+PREFIX_WATCHB))
|
||||
#define lsACCESS_WATCHB *((PTRINT *)(ls+PREFIX_WATCHB))
|
1840
clausesets.c
Normal file
1840
clausesets.c
Normal file
File diff suppressed because it is too large
Load Diff
12
clausesets.h
Normal file
12
clausesets.h
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
/* 2010 (C) Jussi Rintanen */
|
||||
|
||||
/* Literal and types:
|
||||
|
||||
*/
|
||||
|
||||
#define UNASS -1
|
||||
|
||||
int propagate(satinstance);
|
||||
|
||||
void init_clausesets();
|
259
cleanup.c
Normal file
259
cleanup.c
Normal file
@ -0,0 +1,259 @@
|
||||
|
||||
/* 2012 (C) Jussi Rintanen jrintanen.jr@gmail.com */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "asyntax.h"
|
||||
#include "intsets.h"
|
||||
#include "ordintsets.h"
|
||||
#include "operators.h"
|
||||
|
||||
#define noDEBUG
|
||||
|
||||
int unconditional(int l,fma *f) {
|
||||
fmalist *fs;
|
||||
switch(f->t) {
|
||||
case disj:
|
||||
return 0;
|
||||
case conj:
|
||||
fs = f->juncts;
|
||||
while(fs != NULL) {
|
||||
if(unconditional(l,fs->hd)) return 1;
|
||||
fs = fs->tl;
|
||||
}
|
||||
return 0;
|
||||
break;
|
||||
case natom:
|
||||
if(feNLIT(f->a) == l) return 1;
|
||||
return 0;
|
||||
break;
|
||||
case patom:
|
||||
if(fePLIT(f->a) == l) return 1;
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int doesnothing(fma *p,eff *e) {
|
||||
int *l;
|
||||
while(e != NULL) {
|
||||
l = e->effectlits;
|
||||
while(*l != -1) {
|
||||
if(!unconditional(*l,p)) return 0;
|
||||
l = l + 1;
|
||||
}
|
||||
e = e->tl;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Remove operators which don't do anything. */
|
||||
|
||||
void cleanupoperatorsNOOP() {
|
||||
int i;
|
||||
int removed;
|
||||
removed = 0;
|
||||
for(i=0;i<nOfActions;i++) {
|
||||
again:
|
||||
if(doesnothing(actions[i].precon,&(actions[i].effects))) {
|
||||
removed += 1;
|
||||
actions[i] = actions[nOfActions-1];
|
||||
nOfActions -= 1;
|
||||
if(i <= nOfActions-1) goto again;
|
||||
}
|
||||
}
|
||||
if(debugOutput > 1 && removed) printf("Removed %i actions with inconsistent effects.\n",removed);
|
||||
}
|
||||
|
||||
/* Remove operators with inconsistent effects. */
|
||||
|
||||
int inconsistentp(int *ls) {
|
||||
int *i,*j;
|
||||
i = ls;
|
||||
while(*i != -1) {
|
||||
j = i+1;
|
||||
while(*j != -1) {
|
||||
if(*j == feNEG(*i)) return 1;
|
||||
j = j + 1;
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cleanupoperators0() {
|
||||
int i;
|
||||
int removed;
|
||||
eff *e;
|
||||
removed = 0;
|
||||
for(i=0;i<nOfActions;i++) {
|
||||
again:
|
||||
e = &(actions[i].effects);
|
||||
while(e != NULL) {
|
||||
if(inconsistentp(e->effectlits)) {
|
||||
removed += 1;
|
||||
actions[i] = actions[nOfActions-1];
|
||||
nOfActions -= 1;
|
||||
if(i <= nOfActions-1) goto again;
|
||||
}
|
||||
e = e->tl;
|
||||
}
|
||||
}
|
||||
if(debugOutput > 1 && removed) printf("Removed %i actions with inconsistent effects.\n",removed);
|
||||
}
|
||||
|
||||
/* Conform with funny PDDL semantics on actions that _simultaneously_
|
||||
set something both TRUE and FALSE. */
|
||||
|
||||
void removefrom(eff *e) {
|
||||
int *nptr;
|
||||
int *pptr = e->effectlits;
|
||||
while(*pptr != -1) {
|
||||
if(((*pptr)&1) == 0) { /* It's a positive literal. */
|
||||
nptr = e->effectlits;
|
||||
while(*nptr != -1) {
|
||||
if(*nptr == feNEG(*pptr)) { /* Remove positive literal's complement. */
|
||||
while(*nptr != -1) {
|
||||
*nptr = *(nptr+1);
|
||||
nptr = nptr + 1;
|
||||
}
|
||||
pptr = e->effectlits;
|
||||
break;
|
||||
}
|
||||
nptr = nptr + 1;
|
||||
}
|
||||
}
|
||||
pptr = pptr + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Standard PDDL behaviour: if both v:=0 and v:=1, then ignore v:=0. */
|
||||
|
||||
void cleanupoperators1() {
|
||||
int i;
|
||||
int removed;
|
||||
eff *e;
|
||||
removed = 0;
|
||||
for(i=0;i<nOfActions;i++) {
|
||||
e = &(actions[i].effects);
|
||||
while(e != NULL) {
|
||||
removefrom(e);
|
||||
e = e->tl;
|
||||
}
|
||||
}
|
||||
if(debugOutput > 1 && removed) printf("Removed %i actions with inconsistent effects.\n",removed);
|
||||
}
|
||||
|
||||
/* Remove effects that are entailed by the precondition. */
|
||||
|
||||
int entailed(int l,fma *f) {
|
||||
fmalist *fs;
|
||||
|
||||
switch(f->t) {
|
||||
|
||||
case patom: return (l == fePLIT(f->a));
|
||||
case natom: return (l == feNLIT(f->a));
|
||||
|
||||
case conj:
|
||||
fs = f->juncts;
|
||||
while(fs != NULL) {
|
||||
if(entailed(l,fs->hd)) return 1;
|
||||
fs = fs->tl;
|
||||
}
|
||||
return 0;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int aseffect(int l,eff *effects) {
|
||||
int *es;
|
||||
|
||||
while(effects != NULL) {
|
||||
es = effects->effectlits;
|
||||
while(*es != -1) {
|
||||
if(*es == l) return 1;
|
||||
es = es + 1;
|
||||
}
|
||||
effects = effects->tl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int a;
|
||||
|
||||
void removeredundante(eff *alleffects,eff *e,fma *f) {
|
||||
int *rp,*wp;
|
||||
|
||||
rp = e->effectlits;
|
||||
wp = rp;
|
||||
|
||||
while(*rp != -1) {
|
||||
|
||||
*wp = *rp;
|
||||
|
||||
if((!entailed(*wp,f) && !entailed(*wp,e->condition))
|
||||
|| (aseffect(feNEG(*wp),alleffects))) {
|
||||
wp = wp + 1;
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
printf("Removing effect ");
|
||||
if((*wp) & 1) printf("NOT ");
|
||||
printatomi(feVAR(*wp));
|
||||
printf(" in action %i\n",a);
|
||||
#endif
|
||||
}
|
||||
rp = rp + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void removeredundanteffects() {
|
||||
int i;
|
||||
eff *e;
|
||||
for(i=0;i<nOfActions;i++) {
|
||||
a = i;
|
||||
e = &(actions[i].effects);
|
||||
while(e != NULL) {
|
||||
removeredundante(&(actions[i].effects),e,actions[i].precon);
|
||||
e = e->tl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cleanupoperators() {
|
||||
int i;
|
||||
if(flagPDDLadddel) cleanupoperators1();
|
||||
else cleanupoperators0();
|
||||
// removeredundanteffects();
|
||||
cleanupoperatorsNOOP();
|
||||
// printf("After simplifications: %i actions\n",nOfActions);
|
||||
|
||||
if(planSemantics == EStepOgata) {
|
||||
/* Randomly shuffle the action array. */
|
||||
|
||||
for(i=0;i<nOfActions;i++) {
|
||||
int *l;
|
||||
fma *f;
|
||||
eff e;
|
||||
int j;
|
||||
|
||||
j = random() % nOfActions;
|
||||
|
||||
l = actions[i].name;
|
||||
f = actions[i].precon;
|
||||
e = actions[i].effects;
|
||||
|
||||
actions[i].name = actions[j].name;
|
||||
actions[i].precon = actions[j].precon;
|
||||
actions[i].effects = actions[j].effects;
|
||||
|
||||
actions[j].name = l;
|
||||
actions[j].precon = f;
|
||||
actions[j].effects = e;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
4
cleanup.h
Normal file
4
cleanup.h
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
/* 2012 (C) Jussi Rintanen */
|
||||
|
||||
void cleanupoperators();
|
4
dimacs.h
Normal file
4
dimacs.h
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
/* 2012 (C) Jussi Rintanen */
|
||||
|
||||
void dimacsheader(FILE *,int,int);
|
157
dimacsinput.c
Normal file
157
dimacsinput.c
Normal file
@ -0,0 +1,157 @@
|
||||
|
||||
/* 2010 (C) Jussi Rintanen */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "interface.h"
|
||||
#include "clausedb.h"
|
||||
#include "main.h"
|
||||
|
||||
#define noDEBUG
|
||||
|
||||
int lineno;
|
||||
|
||||
void nextline(FILE *f) {
|
||||
char c;
|
||||
do {
|
||||
c = getc(f);
|
||||
} while(c != '\n');
|
||||
lineno += 1;
|
||||
}
|
||||
|
||||
int numeric(char c) { return '0' <= c && c <= '9'; }
|
||||
int numvalue(char c) { return c-'0'; }
|
||||
|
||||
int readnat(FILE *f) {
|
||||
char c;
|
||||
int i;
|
||||
do {
|
||||
c = getc(f);
|
||||
if(c == '%') nextline(f);
|
||||
if(c == '\n') lineno += 1;
|
||||
} while (c == ' ' || c == '\n' || c == '\t' || c == '%');
|
||||
i = 0;
|
||||
if(! numeric(c)) {
|
||||
fprintf(stderr,"Found illegal character %c on line %i ... exiting.\n",c,lineno);
|
||||
exit(0);
|
||||
}
|
||||
i = numvalue(c);
|
||||
do {
|
||||
c = getc(f);
|
||||
if(numeric(c)) i = i*10+numvalue(c);
|
||||
} while(numeric(c));
|
||||
ungetc(c,f);
|
||||
return i;
|
||||
}
|
||||
|
||||
int readint(FILE *f) {
|
||||
char c;
|
||||
int i;
|
||||
int neg;
|
||||
neg = 0;
|
||||
do {
|
||||
c = getc(f);
|
||||
if(c == '%') nextline(f);
|
||||
if(c == '\n') lineno += 1;
|
||||
} while (c == ' ' || c == '\n' || c == '\t' || c == '%');
|
||||
i = 0;
|
||||
if((! numeric(c)) && (c != '-')) {
|
||||
fprintf(stderr,"Found illegal character %c on line %i ... exiting.\n",c,lineno);
|
||||
exit(0);
|
||||
}
|
||||
if(c == '-') {
|
||||
neg = 1; i = 0;
|
||||
} else i = numvalue(c);
|
||||
do {
|
||||
c = getc(f);
|
||||
if(numeric(c)) i = i*10+numvalue(c);
|
||||
} while(numeric(c));
|
||||
ungetc(c,f);
|
||||
return neg ? 0-i : i;
|
||||
}
|
||||
|
||||
int dsatlit(int l) {
|
||||
if(l < 0) return ((-l-1) << 1)|1;
|
||||
return ((l-1) << 1);
|
||||
}
|
||||
|
||||
int inputclause[100000];
|
||||
|
||||
satinstance DIMACSinput() {
|
||||
FILE *f;
|
||||
satinstance sati;
|
||||
int i,len,j,n;
|
||||
char c;
|
||||
int numberOfProps;
|
||||
int numberOfClauses;
|
||||
|
||||
if(nOfInputFiles != 1) {
|
||||
fprintf(stderr,"ERROR: DIMACS input has to be exactly one file!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f = fopen(inputfiles[0],"r");
|
||||
if(f == NULL) {
|
||||
fprintf(stderr,"ERROR: could not open file '%s'\n",inputfiles[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
lineno = 1;
|
||||
|
||||
initclausedb();
|
||||
|
||||
numberOfProps = -1;
|
||||
numberOfClauses = -1;
|
||||
|
||||
while(1 == 1) {
|
||||
c = getc(f);
|
||||
switch(c) {
|
||||
case 'c': nextline(f); break;
|
||||
case 'p':
|
||||
printf("Reading DIMACS header\n");
|
||||
do { c = getc(f); } while(c != 'c');
|
||||
do { c = getc(f); } while(c != 'n');
|
||||
do { c = getc(f); } while(c != 'f');
|
||||
numberOfProps = readnat(f);
|
||||
numberOfClauses = readnat(f);
|
||||
printf("%i variables %i clauses\n",numberOfProps,numberOfClauses);
|
||||
nextline(f);
|
||||
break;
|
||||
default:
|
||||
ungetc(c,f);
|
||||
goto preambleended;
|
||||
}
|
||||
}
|
||||
preambleended:
|
||||
|
||||
sati = newinstance(1,1,numberOfProps,0,0);
|
||||
|
||||
for(i=0;i<numberOfClauses;i++) {
|
||||
|
||||
len = 0;
|
||||
do {
|
||||
n = readint(f);
|
||||
inputclause[len] = n;
|
||||
len += 1;
|
||||
} while(n != 0);
|
||||
|
||||
len = len-1;
|
||||
|
||||
switch(len) {
|
||||
case 1: add1clause(sati,dsatlit(inputclause[0]),InitC); break;
|
||||
case 2:
|
||||
add2clause(sati,dsatlit(inputclause[0]),dsatlit(inputclause[1]),InitC);
|
||||
break;
|
||||
default:
|
||||
#ifdef DEBUG
|
||||
printf("adding clause of length %i\n",len);
|
||||
#endif
|
||||
addnewclause(sati,len,InitC);
|
||||
for(j=0;j<len;j++) addliteral(sati,j,dsatlit(inputclause[j]));
|
||||
finishclause(sati);
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
printf("Finished reading file.\n");
|
||||
return sati;
|
||||
}
|
4
dimacsinput.h
Normal file
4
dimacsinput.h
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
/* 2010 (C) Jussi Rintanen */
|
||||
|
||||
satinstance DIMACSinput();
|
812
ground.c
Normal file
812
ground.c
Normal file
@ -0,0 +1,812 @@
|
||||
|
||||
/* 2012 (C) Jussi Rintanen jrintanen.jr@gmail.com */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "asyntax.h"
|
||||
#include "tables.h"
|
||||
#include "intsets.h"
|
||||
#include "ordintsets.h"
|
||||
#include "operators.h"
|
||||
#include "main.h"
|
||||
//#include "instantiation.h"
|
||||
|
||||
#define noDEBUG
|
||||
|
||||
/*****************************************************************************/
|
||||
/*************************** Preprocess **************************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
int binding[200];
|
||||
int nOfBindings;
|
||||
int scope[200];
|
||||
|
||||
#ifdef CFMA
|
||||
#include "Cground.c"
|
||||
#endif
|
||||
|
||||
/* replace parameter variables by their index in the parameter list */
|
||||
|
||||
int NEWparamindex(int i,int qdepth) {
|
||||
int j;
|
||||
for(j=qdepth-1;j>=0;j--) {
|
||||
if(scope[j] == i) return -1-j;
|
||||
}
|
||||
fprintf(stderr,"ERROR: variable %s is not a parameter\n",symbol(i));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* This applies paramindex in the right places */
|
||||
|
||||
void NEWpreprocessatom(atom a,int qdepth) {
|
||||
int i;
|
||||
for(i=2;i<2+a[1];i++) {
|
||||
if(isvar(a[i])) {
|
||||
a[i] = NEWparamindex(a[i],qdepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This applies paramindex in the right places. */
|
||||
/* For quantification, this replaces the quantified variables name
|
||||
with the next available integer index. */
|
||||
|
||||
void NEWpreprocessfma(Sfma *f,int qdepth) {
|
||||
Sfmalist *l;
|
||||
switch(Sfmatypeof(f)) {
|
||||
case STRUE:
|
||||
case SFALSE:
|
||||
break;
|
||||
case Spatom:
|
||||
case Snatom:
|
||||
NEWpreprocessatom(f->a,qdepth);
|
||||
break;
|
||||
case Sdisj:
|
||||
case Sconj:
|
||||
#ifdef CFMA
|
||||
f->cnt = listlen(f->juncts);
|
||||
#endif
|
||||
l = f->juncts;
|
||||
while(l != NULL) {
|
||||
NEWpreprocessfma(l->hd,qdepth);
|
||||
l = l->tl;
|
||||
}
|
||||
break;
|
||||
case Sforall:
|
||||
case Sforsome:
|
||||
if(f->ss->tl) { /* Split multiple quantification. */
|
||||
Sfma *f1 = (Sfma*)malloc(sizeof(Sfma));
|
||||
f1->t = f->t;
|
||||
f1->ss = f->ss->tl;
|
||||
f1->f = f->f;
|
||||
|
||||
f->ss->tl = NULL;
|
||||
f->f = f1;
|
||||
}
|
||||
scope[qdepth] = f->ss->v;
|
||||
#ifdef DEBUG
|
||||
printf("scope[%i] = %s\n",qdepth,symbol(f->ss->v));
|
||||
#endif
|
||||
f->ss->v = -1-qdepth;
|
||||
NEWpreprocessfma(f->f,qdepth+1);
|
||||
break;
|
||||
case Seq:
|
||||
case Sneq:
|
||||
if(isvar(f->p1)) f->p1 = NEWparamindex(f->p1,qdepth);
|
||||
if(isvar(f->p2)) f->p2 = NEWparamindex(f->p2,qdepth);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* This applies paramindex in the right places */
|
||||
|
||||
void NEWpreprocesseff(Seff *e,int qdepth) {
|
||||
Sfmalist *l;
|
||||
switch(e->t) {
|
||||
case SEpatom:
|
||||
case SEnatom:
|
||||
NEWpreprocessatom(e->a,qdepth);
|
||||
break;
|
||||
case SEconj:
|
||||
l = e->juncts;
|
||||
while(l != NULL) {
|
||||
NEWpreprocesseff(l->hd,qdepth);
|
||||
l = l->tl;
|
||||
}
|
||||
break;
|
||||
case SEforall:
|
||||
if(e->ss->tl) { /* Split multiple quantification. */
|
||||
Seff *e1 = (Seff*)malloc(sizeof(Seff));
|
||||
e1->t = SEforall;
|
||||
e1->ss = e->ss->tl;
|
||||
e1->effect = e->effect;
|
||||
|
||||
e->ss->tl = NULL;
|
||||
e->effect = e1;
|
||||
}
|
||||
scope[qdepth] = e->ss->v;
|
||||
#ifdef DEBUG
|
||||
printf("scope[%i] = %s\n",qdepth,symbol(e->ss->v));
|
||||
#endif
|
||||
e->ss->v = -1-qdepth;
|
||||
NEWpreprocesseff(e->effect,qdepth+1);
|
||||
break;
|
||||
case SEwhen:
|
||||
NEWpreprocessfma(e->cond,qdepth);
|
||||
NEWpreprocesseff(e->effect,qdepth);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NEWpreprocessoperators() {
|
||||
int i,qdepth;
|
||||
typedvarlist *ps;
|
||||
|
||||
for(i=0;i<nOfSActions;i++) {
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("BEFORE:\n");
|
||||
if(flagShowInput) printSaction(&Sactions[i]);
|
||||
#endif
|
||||
|
||||
qdepth = 0;
|
||||
ps = Sactions[i].params;
|
||||
|
||||
while(ps != NULL) {
|
||||
#ifdef DEBUG
|
||||
printf("scope[%i] = %s\n",qdepth,symbol(ps->v));
|
||||
#endif
|
||||
scope[qdepth++] = ps->v;
|
||||
ps = ps->tl;
|
||||
}
|
||||
|
||||
// printf("Qdepth = %i\n",qdepth);
|
||||
NEWpreprocessfma(Sactions[i].precon,qdepth);
|
||||
NEWpreprocesseff(Sactions[i].effect,qdepth);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("AFTER:\n");
|
||||
#endif
|
||||
if(flagShowInput) printSaction(&Sactions[i]);
|
||||
}
|
||||
NEWpreprocessfma(Sgoal,0);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/********************************* Grounding *******************************/
|
||||
/***************************************************************************/
|
||||
|
||||
Sfma *whenstack[1000]; /* Array for nested when-conditions */
|
||||
|
||||
int NEWnOfEffectLitsL(Sefflist *);
|
||||
|
||||
int NEWnOfEffectLits(Seff *se) {
|
||||
switch(se->t) {
|
||||
case SEpatom: return 1;
|
||||
case SEnatom: return 1;
|
||||
case SEconj: return NEWnOfEffectLitsL(se->juncts);
|
||||
case SEwhen: return 0;
|
||||
case SEforall: return (getdomainsize(se->ss->t)) * NEWnOfEffectLits(se->effect);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int NEWnOfEffectLitsL(Sefflist *l) {
|
||||
if(l == NULL) return 0;
|
||||
return NEWnOfEffectLits(l->hd) + NEWnOfEffectLitsL(l->tl);
|
||||
}
|
||||
|
||||
int *NEWinserteffectlitsL(int *,Sefflist *,int *);
|
||||
|
||||
int *NEWinserteffectlits(int *a,Seff *se,int *b) {
|
||||
int *vals;
|
||||
switch(se->t) {
|
||||
case SEpatom: *a = fePLIT(atomindex(se->a,b)); return a+1;
|
||||
case SEnatom: *a = feNLIT(atomindex(se->a,b)); return a+1;
|
||||
case SEconj: return NEWinserteffectlitsL(a,se->juncts,b);
|
||||
case SEwhen: return a;
|
||||
case SEforall:
|
||||
vals = getdomain(se->ss->t);
|
||||
while(*vals != -1) {
|
||||
b[-1-se->ss->v] = *vals;
|
||||
|
||||
a = NEWinserteffectlits(a,se->effect,b);
|
||||
|
||||
vals = vals + 1;
|
||||
}
|
||||
return a;
|
||||
|
||||
default: return a;
|
||||
}
|
||||
}
|
||||
|
||||
int *NEWinserteffectlitsL(int *a,Sefflist *l,int *b) {
|
||||
if(l == NULL) return a;
|
||||
return NEWinserteffectlitsL(NEWinserteffectlits(a,l->hd,b),l->tl,b);
|
||||
}
|
||||
|
||||
int someunconditional(Seff *se) {
|
||||
Sefflist *ses;
|
||||
switch(se->t) {
|
||||
case SEconj:
|
||||
ses = se->juncts;
|
||||
while(ses != NULL) {
|
||||
if(someunconditional(ses->hd)) return 1;
|
||||
ses = ses->tl;
|
||||
}
|
||||
return 0;
|
||||
case SEpatom: return 1;
|
||||
case SEnatom: return 1;
|
||||
case SEwhen: return 0;
|
||||
case SEforall: return someunconditional(se->effect);
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
fma *NEWgroundfma(Sfma *,int *);
|
||||
|
||||
eff *NEWlocateconditionals(Seff *se,int *b,eff *ac,int whennesting) {
|
||||
int *vals,i,*ptr;
|
||||
eff *e,*ac0;
|
||||
Sefflist *ses;
|
||||
|
||||
switch(se->t) {
|
||||
|
||||
case SEconj:
|
||||
ses = se->juncts;
|
||||
while(ses != NULL) {
|
||||
ac = NEWlocateconditionals(ses->hd,b,ac,whennesting);
|
||||
ses = ses->tl;
|
||||
}
|
||||
return ac;
|
||||
|
||||
case SEwhen:
|
||||
e = (eff *)malloc(sizeof(eff));
|
||||
|
||||
whenstack[whennesting] = se->cond;
|
||||
ac0 = NEWlocateconditionals(se->effect,b,ac,whennesting+1);
|
||||
|
||||
if(se->cond->t == SFALSE) return ac0;
|
||||
if(!someunconditional(se->effect)) return ac0;
|
||||
|
||||
if(whennesting == 0) { /* Non-nested when */
|
||||
|
||||
e->condition = NEWgroundfma(se->cond,b);
|
||||
#ifdef CFMA
|
||||
e->ccondition = Cgroundfma(se->cond,b);
|
||||
// printcfma(e->ccondition);
|
||||
#endif
|
||||
|
||||
} else{ /* Nesting of 2 or more whens */
|
||||
|
||||
fmalist *fs = NULL;
|
||||
for(i=0;i<=whennesting;i++) {
|
||||
fs = fmacons(NEWgroundfma(whenstack[i],b),fs);
|
||||
}
|
||||
e->condition = (fma *)malloc(sizeof(fma));
|
||||
e->condition->t = conj;
|
||||
e->condition->juncts = fs;
|
||||
}
|
||||
|
||||
e->effectlits = (int *)malloc((NEWnOfEffectLits(se->effect)+1) * sizeof(int));
|
||||
ptr = NEWinserteffectlits(e->effectlits,se->effect,b);
|
||||
*ptr = -1;
|
||||
e->tl = ac0;
|
||||
return e;
|
||||
|
||||
case SEforall:
|
||||
|
||||
vals = getdomain(se->ss->t);
|
||||
|
||||
while(*vals != -1) {
|
||||
b[-1-se->ss->v] = *vals;
|
||||
|
||||
ac = NEWlocateconditionals(se->effect,b,ac,whennesting);
|
||||
|
||||
vals = vals + 1;
|
||||
}
|
||||
return ac;
|
||||
|
||||
default: return ac;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NEWgroundeff(Seff *se,int *b, eff *e) {
|
||||
int *ptr,cnt;
|
||||
// eff *e = (eff *)malloc(sizeof(eff));
|
||||
e->condition = (fma *)malloc(sizeof(fma));
|
||||
e->condition->t = TRUE;
|
||||
#ifdef CFMA
|
||||
e->ccondition = cTRUE;
|
||||
#endif
|
||||
cnt = NEWnOfEffectLits(se);
|
||||
// printf("There are %i effect literals: ",cnt);
|
||||
e->effectlits = (int *)malloc((cnt+1) * sizeof(int));
|
||||
ptr = NEWinserteffectlits(e->effectlits,se,b);
|
||||
*ptr = -1;
|
||||
// printlitarr(e->effectlits);
|
||||
e->tl = NEWlocateconditionals(se,b,NULL,0);
|
||||
}
|
||||
|
||||
fmalist *NEWgroundfmalist(Sfmalist *,int *);
|
||||
|
||||
fma *NEWgroundfma(Sfma *sf,int *b) {
|
||||
int *vals;
|
||||
fma *f = (fma *)malloc(sizeof(fma));
|
||||
|
||||
switch(Sfmatypeof(sf)) {
|
||||
|
||||
case STRUE: f->t = TRUE; break;
|
||||
case SFALSE: f->t = FALSE; break;
|
||||
|
||||
case Sconj:
|
||||
f->t = conj;
|
||||
f->juncts = NEWgroundfmalist(sf->juncts,b);
|
||||
break;
|
||||
|
||||
case Sdisj:
|
||||
f->t = disj;
|
||||
f->juncts = NEWgroundfmalist(sf->juncts,b);
|
||||
break;
|
||||
|
||||
case Seq:
|
||||
if(bvalue(sf->p1,b) == bvalue(sf->p2,b)) {
|
||||
f->t = TRUE;
|
||||
} else {
|
||||
f->t = FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case Sneq:
|
||||
if(bvalue(sf->p1,b) == bvalue(sf->p2,b)) {
|
||||
f->t = FALSE;
|
||||
} else {
|
||||
f->t = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case Spatom:
|
||||
f->t = patom;
|
||||
f->a = atomindex(sf->a,b);
|
||||
break;
|
||||
|
||||
case Snatom:
|
||||
f->t = natom;
|
||||
f->a = atomindex(sf->a,b);
|
||||
break;
|
||||
|
||||
case Sforall: /* Iterate over all values of the variable. */
|
||||
|
||||
f->t = conj;
|
||||
f->juncts = NULL;
|
||||
|
||||
vals = getdomain(sf->ss->t);
|
||||
|
||||
while(*vals != -1) {
|
||||
b[-1-sf->ss->v] = *vals;
|
||||
f->juncts = fmacons(NEWgroundfma(sf->f,b),f->juncts);
|
||||
vals = vals + 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case Sforsome: /* Iterate over all values of the variable. */
|
||||
|
||||
f->t = disj;
|
||||
f->juncts = NULL;
|
||||
|
||||
vals = getdomain(sf->ss->t);
|
||||
|
||||
while(*vals != -1) {
|
||||
b[-1-sf->ss->v] = *vals;
|
||||
f->juncts = fmacons(NEWgroundfma(sf->f,b),f->juncts);
|
||||
vals = vals + 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
fmalist *NEWgroundfmalist(Sfmalist *l,int *b) {
|
||||
if(l == NULL) return NULL;
|
||||
return fmacons(NEWgroundfma(l->hd,b),NEWgroundfmalist(l->tl,b));
|
||||
}
|
||||
|
||||
/* Is it a variable, and not assigned? */
|
||||
|
||||
inline int assignedvar(int v,int i) {
|
||||
if(v < 0 && (-1-v) <= i) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
/* Check all static atomic conjuncts of precon to found out whether the bindings
|
||||
until parameter i are compatible with the initial state. */
|
||||
|
||||
inline int staticp(int i) {
|
||||
return index2stentry[i]->staticpredicate;
|
||||
}
|
||||
|
||||
/*
|
||||
Generate bindings so that the formula f is not trivially violated by
|
||||
the true literals in the initial state in the sense that there is a positive
|
||||
literal as a conjunct of f that is false in the initial state.
|
||||
|
||||
How is this done?
|
||||
*/
|
||||
|
||||
/*
|
||||
Test whether the formula f with the current partial binding is compatible
|
||||
with the true literals in the initial state.
|
||||
This is only tested for positive literals appearing as conjuncts of
|
||||
the formula. All such literals must match the initial state.
|
||||
*/
|
||||
|
||||
int legalstaticbindingA(int i,int *a) {
|
||||
int j;
|
||||
atom *as;
|
||||
|
||||
/* Go through the atoms in the initial state description, and check. */
|
||||
as = Sinit;
|
||||
if(staticp(a[0]) == 0) return 1;
|
||||
while(*as != NULL) { /* Go through all initial state atoms. */
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Matching ");
|
||||
printSfma(f);
|
||||
printf(" against ");
|
||||
printatom(*as);
|
||||
printf(" with");
|
||||
for(j=0;j<=i;j++) {
|
||||
printf(" #%i:%s",j,symbol(binding[j]));
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
if((*as)[0] == a[0]) { /* Same predicate. Binding OK? */
|
||||
for(j=2;j<a[1]+2;j++) { /* Go through parameters. */
|
||||
/* Is it unassigned or a match. */
|
||||
if(assignedvar(a[j],i) && ((*as)[j] != binding[-1-a[j]])) {
|
||||
goto nextinitatom; /* Did not match. */
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("MATCH!\n");
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
nextinitatom:
|
||||
as = as + 1;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("NO MATCH!\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int legalstaticbinding(int i,Sfma *f) {
|
||||
Sfmalist *fs;
|
||||
|
||||
switch(f->t) {
|
||||
|
||||
case Spatom: return legalstaticbindingA(i,f->a);
|
||||
|
||||
case Sconj:
|
||||
fs = f->juncts;
|
||||
while(fs != NULL) {
|
||||
if(legalstaticbinding(i,fs->hd) == 0) return 0;
|
||||
fs = fs->tl;
|
||||
}
|
||||
|
||||
default: return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define noNEWSTATICB
|
||||
#ifdef NEWSTATICB
|
||||
int litcnt;
|
||||
int *trueposlits[1000];
|
||||
int relevantbindings[100000];
|
||||
|
||||
/* General procedure for identifying relevant bindings.
|
||||
Check every conjunct of the precondition and every true variable in
|
||||
the initial state, and check if there is a match, binding the current
|
||||
parameter.
|
||||
Match the first literal first, to identify a candidate value.
|
||||
If there is a second (and further literals), check whether the match
|
||||
is good.
|
||||
*/
|
||||
|
||||
void identifyposlits(int i,Sfma *f) {
|
||||
Sfmalist *fs;
|
||||
int j;
|
||||
|
||||
switch(f->t) {
|
||||
case Spatom:
|
||||
if(!staticp(f->a[0])) return;
|
||||
for(j=0;j<f->a[1];j++) {
|
||||
if(f->a[j+2] == -1-i) {
|
||||
trueposlits[litcnt++] = f->a;
|
||||
printatom(f->a);
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
case Sconj:
|
||||
fs = f->juncts;
|
||||
while(fs != NULL) {
|
||||
identifyposlits(i,fs->hd);
|
||||
fs = fs->tl;
|
||||
}
|
||||
return;
|
||||
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
|
||||
int match(int *patom,int *initlit,int param,int *value) {
|
||||
int i;
|
||||
*value = -1;
|
||||
|
||||
if(initlit[0] != patom[0]) return 0; /* Wrong predicate */
|
||||
if(initlit[1] != patom[1]) return 0; /* Wrong arity */
|
||||
|
||||
for(i=0;i<initlit[1];i++) {
|
||||
if(assignedvar(patom[i+2],param-1) && (binding[-1-patom[i+2]] != initlit[i+2])) return 0;
|
||||
if(patom[i+2] == -1-param) *value = initlit[i+2];
|
||||
}
|
||||
assert(*value != -1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void findrelevantbindings(int i,Sfma *f) {
|
||||
int cnt,j;
|
||||
int value;
|
||||
atom *as;
|
||||
|
||||
litcnt = 0;
|
||||
cnt = 0;
|
||||
|
||||
/* Identify literals that have to be matched. */
|
||||
|
||||
printf("Positive literals with parameter %i are:",i);
|
||||
|
||||
identifyposlits(i,f);
|
||||
assert(litcnt > 0);
|
||||
|
||||
printf("\n");
|
||||
|
||||
/* Match first lit with the initial state to obtain a binding, and
|
||||
verify that others match with this binding. */
|
||||
|
||||
printf("Relevant bindings for parameter %i are...\n",i);
|
||||
|
||||
as = Sinit;
|
||||
|
||||
while(*as != NULL) {
|
||||
printf("Trying match with "); printatom(*as); printf(":");
|
||||
if(match(trueposlits[0],*as,i,&value)) { /* There is a match. */
|
||||
for(j=0;j<cnt;j++) {
|
||||
if(relevantbindings[j] == value) goto hadalready;
|
||||
}
|
||||
relevantbindings[cnt++] = value;
|
||||
printf(" %s OK",symbol(relevantbindings[cnt-1]));
|
||||
}
|
||||
|
||||
hadalready:
|
||||
printf("\n");
|
||||
|
||||
as = as + 1;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
relevantbindings[cnt] = -1; /* The list is terminated with -1. */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* produce list with parameter values */
|
||||
|
||||
void copybindings(int *dest,int *binding,int bindings) {
|
||||
int i;
|
||||
for(i=0;i<bindings;i++) dest[i] = binding[i];
|
||||
dest[bindings] = -1;
|
||||
}
|
||||
|
||||
/* Go through all bindings.
|
||||
i which variable to bind (0..nOfBindings-1)
|
||||
sc which schema are we instantiating
|
||||
domains[] the values for each of the variables 0..nOfBindings-1
|
||||
staticrestriction whether variable i is restricted by a static fact
|
||||
*/
|
||||
|
||||
|
||||
void NEWgothrough(int i,int sc,int **domains,int *staticrestriction) {
|
||||
if(i < nOfBindings) { /* base case, instantiate */
|
||||
int *l = domains[i]; /* Values in the domain for the ith variable. */
|
||||
|
||||
/* Some of the variables are limited by their occurrence in a static
|
||||
predicate that is a necessary precondition. In those cases go
|
||||
only through the allowed values of the variable. */
|
||||
|
||||
if(staticrestriction[i]) { /* Restricted by a static predicate. */
|
||||
|
||||
#ifdef NEWSTATICB
|
||||
/* Find relevant bindings by one traversal of the initial literals. */
|
||||
|
||||
findrelevantbindings(i,Sactions[sc].precon);
|
||||
l = &relevantbindings;
|
||||
#endif
|
||||
|
||||
/* PROBLEM: This can be really bad. Why don't you just generate
|
||||
sensible bindings by going through the initial state, rather
|
||||
than go through all possible domain values and test for each
|
||||
whether it is sanctioned by the initial state? */
|
||||
|
||||
while(*l != -1) {
|
||||
|
||||
binding[i] = *l;
|
||||
// printf("(%s)",symbol(l->hd));
|
||||
#ifdef DEBUG
|
||||
printf("----------------------------------\n");
|
||||
#endif
|
||||
|
||||
#ifdef NEWSTATICB
|
||||
NEWgothrough(i+1,sc,domains,staticrestriction);
|
||||
#else
|
||||
if(legalstaticbinding(i,Sactions[sc].precon)) { /* Legal binding? */
|
||||
NEWgothrough(i+1,sc,domains,staticrestriction);
|
||||
}
|
||||
#endif
|
||||
|
||||
l = l + 1;
|
||||
}
|
||||
} else {
|
||||
|
||||
/* Value not restricted by a static predicate. */
|
||||
|
||||
while(*l != -1) {
|
||||
binding[i] = *l;
|
||||
// printf("(%s)",symbol(l->hd));
|
||||
NEWgothrough(i+1,sc,domains,staticrestriction);
|
||||
l = l + 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("INSTANTIATE\n");
|
||||
#endif
|
||||
|
||||
nOfActions += 1;
|
||||
|
||||
if(nOfActions >= maxActions) {
|
||||
maxActions = 2*maxActions;
|
||||
actions = (action *)realloc(actions,maxActions * sizeof(action));
|
||||
}
|
||||
|
||||
actions[nOfActions-1].name = (int *)malloc((nOfBindings+2) * sizeof(int));
|
||||
actions[nOfActions-1].name[0] = Sactions[sc].name;
|
||||
copybindings(actions[nOfActions-1].name+1,binding,nOfBindings);
|
||||
|
||||
actions[nOfActions-1].precon = NEWgroundfma(Sactions[sc].precon,binding);
|
||||
#ifdef CFMA
|
||||
actions[nOfActions-1].cprecon = Cgroundfma(Sactions[sc].precon,binding);
|
||||
// printcfma(actions[nOfActions-1].cprecon);
|
||||
#endif
|
||||
NEWgroundeff(Sactions[sc].effect,binding,&(actions[nOfActions-1].effects));
|
||||
actions[nOfActions-1].cost = Sactions[sc].cost;
|
||||
|
||||
// printaction(nOfActions-1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Does parameter i occur in a static positive literal, a conjunct of f? */
|
||||
|
||||
int occursinstatic(int i,Sfma *f) {
|
||||
Sfmalist *fs;
|
||||
int j;
|
||||
|
||||
switch(f->t) {
|
||||
case Spatom:
|
||||
if(!staticp(f->a[0])) return 0;
|
||||
for(j=0;j<f->a[1];j++) {
|
||||
if(f->a[j+2] == -1-i) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
case Sconj:
|
||||
fs = f->juncts;
|
||||
while(fs != NULL) {
|
||||
if(occursinstatic(i,fs->hd)) return 1;
|
||||
fs = fs->tl;
|
||||
}
|
||||
return 0;
|
||||
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void NEWgroundoperators() {
|
||||
int i,j;
|
||||
int *domains[1000];
|
||||
int binding[1000];
|
||||
int staticrestriction[1000];
|
||||
atom *al;
|
||||
|
||||
NEWpreprocessoperators();
|
||||
|
||||
initactions(); /* initialize the ground action data structure */
|
||||
initatomtable(); /* initialize the tables for atoms */
|
||||
|
||||
for(i=0;i<nOfSActions;i++) {
|
||||
typedvarlist *params = Sactions[i].params;
|
||||
typedvarlist *l = params;
|
||||
|
||||
if(flagShowInput) {
|
||||
printf("Grounding schema %i:%s\n",i,symbol(Sactions[i].name));
|
||||
printSaction(&Sactions[i]);
|
||||
}
|
||||
|
||||
/* Fetch domains of the parameters */
|
||||
nOfBindings = 0;
|
||||
while(l != NULL) {
|
||||
staticrestriction[nOfBindings] = occursinstatic(nOfBindings,Sactions[i].precon);
|
||||
#ifdef DEBUG
|
||||
if(staticrestriction[nOfBindings]) {
|
||||
printf("Parameter %i is static.\n",nOfBindings);
|
||||
printSaction(&Sactions[i]);
|
||||
} else { printf("."); }
|
||||
#endif
|
||||
#ifdef ASSERTS
|
||||
assert(isvar(l->v));
|
||||
#endif
|
||||
domains[nOfBindings] = getdomain(l->t);
|
||||
nOfBindings += 1;
|
||||
l = l->tl;
|
||||
}
|
||||
|
||||
#ifdef ASSERTS
|
||||
assert(nOfBindings < 100);
|
||||
#endif
|
||||
|
||||
/* Go through all parameter assignments and ground */
|
||||
|
||||
NEWgothrough(0,i,domains,staticrestriction);
|
||||
|
||||
}
|
||||
|
||||
goal = NEWgroundfma(Sgoal,binding);
|
||||
|
||||
/* Go through the initial state description to assign
|
||||
indices to initial state atoms. */
|
||||
|
||||
al = Sinit;
|
||||
while(*al != NULL) {
|
||||
atomindex(*al,NULL);
|
||||
al = al + 1;
|
||||
}
|
||||
|
||||
initialstate = (int *)malloc(sizeof(int) * nOfAtoms);
|
||||
for(i=0;i<nOfAtoms;i++) initialstate[i] = 0;
|
||||
|
||||
al = Sinit;
|
||||
while(*al != NULL) {
|
||||
j = atomindex(*al,NULL);
|
||||
initialstate[j] = 1;
|
||||
|
||||
#ifdef ASSERTS
|
||||
assert(j>=0); assert(j<nOfAtoms);
|
||||
#endif
|
||||
|
||||
al = al + 1;
|
||||
}
|
||||
|
||||
}
|
828
heuristics2.c
Normal file
828
heuristics2.c
Normal file
@ -0,0 +1,828 @@
|
||||
|
||||
/* 2012 (C) Jussi Rintanen */
|
||||
|
||||
#define noDECDEBUG
|
||||
#define noHEURDEBUG
|
||||
#define noDEBUGDISJ
|
||||
|
||||
typedef struct {
|
||||
int l; /* Will satisfy subgoal l */
|
||||
int var; /* with variable var (action, conditional effect) */
|
||||
short t; /* at time point t */
|
||||
int flaws; /* How many later actions this action disables/affects */
|
||||
} planstep;
|
||||
|
||||
#define MAXPLANSTEPS 1000000
|
||||
planstep plansteps[MAXPLANSTEPS];
|
||||
int Nsteps;
|
||||
|
||||
#define STACKSIZE 50000
|
||||
typedef struct _stackel {
|
||||
int lit;
|
||||
short t;
|
||||
short val;
|
||||
} stackel;
|
||||
|
||||
int stackptr;
|
||||
stackel stack[STACKSIZE];
|
||||
|
||||
/* Order the subgoals according to a measure.
|
||||
0. No measure is used (everything is 0).
|
||||
1. How early does it have to be true.
|
||||
TODO: 2. How early, + how constrained.
|
||||
If two are equally early, choose the one that is more constrained
|
||||
in the sense that can be TRUE in a smaller number of consecutive
|
||||
time points. Choosing a highly constrained subgoal leads to failures
|
||||
sooner.
|
||||
*/
|
||||
|
||||
inline int anyactionapplicable(satinstance sati,int l,int t) {
|
||||
compactCEstruct *ptr;
|
||||
for(ptr=cCEs[l];ptr->var != -1;ptr++) { /* All ways of making l true. */
|
||||
if(!tvarfalsep(sati,ptr->var,t)) { /* Is it applicable? */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int goallitvalue(satinstance sati,int l,int t0) {
|
||||
int t,t2;
|
||||
t = t0;
|
||||
switch(HEURordmode) {
|
||||
case 1:
|
||||
/* How long the goal lit has been true before t. */
|
||||
while(t >= 0 && tlittruep(sati,l,t)) t = t - 1;
|
||||
return t+1;
|
||||
case 2:
|
||||
/* How long the goal lit has been true before t. */
|
||||
while(t >= 0 && tlittruep(sati,l,t)) t = t - 1;
|
||||
t2 = t;
|
||||
/* How much earlier it was last false. */
|
||||
while(t2 >= 0 && !tlitfalsep(sati,l,t2)) t2 = t2-1;
|
||||
return (t+1)*200+(t-t2);
|
||||
case 3:
|
||||
/* How long the goal lit must have been true before t (check applicability
|
||||
of actions making it true!) */
|
||||
t = t-1;
|
||||
while(t >= 0 && anyactionapplicable(sati,l,t) == 0) t = t - 1;
|
||||
return t+1;
|
||||
case 4:
|
||||
/* How wide is the gap in which it must be made true? */
|
||||
/* WARNING: This stops depth-first! */
|
||||
t = t-1;
|
||||
while(t >= 0 && anyactionapplicable(sati,l,t) == 0) t = t - 1;
|
||||
t2 = t;
|
||||
while(t2 >= 0 && !tlitfalsep(sati,l,t2)) t2 = t2 - 1;
|
||||
return t-t2;
|
||||
case 5:
|
||||
/* Case 1 with Case 4 as a tie-breaker. */
|
||||
/* How wide is the gap in which it must be made true? */
|
||||
t = t-1;
|
||||
while(t >= 0 && tlittruep(sati,l,t)) t = t - 1;
|
||||
t2 = t;
|
||||
while(t2 >= 0 && !tlitfalsep(sati,l,t2)) t2 = t2 - 1;
|
||||
return t*1000+t-t2;
|
||||
case 6:
|
||||
/* Case 3 with Case 4 as a tie-breaker. */
|
||||
/* How wide is the gap in which it must be made true? */
|
||||
t = t-1;
|
||||
while(t >= 0 && anyactionapplicable(sati,l,t) == 0) t = t - 1;
|
||||
t2 = t;
|
||||
while(t2 >= 0 && !tlitfalsep(sati,l,t2)) t2 = t2 - 1;
|
||||
return t*1000+t-t2;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void push2goalstack(satinstance sati,int l,int t) {
|
||||
int v,i;
|
||||
|
||||
i = stackptr++;
|
||||
|
||||
ASSERT(stackptr < STACKSIZE);
|
||||
|
||||
v = goallitvalue(sati,l,t);
|
||||
|
||||
/* Insert the literal in the stack. Lowest .val is on top (last). */
|
||||
/* This means that we have a depth-first traversal: support for
|
||||
one precondition (or top-level goal) is found first, before
|
||||
proceeding with another precondition (or top-level goal). */
|
||||
|
||||
while(i > 0 && stack[i-1].val < v) {
|
||||
stack[i].lit = stack[i-1].lit;
|
||||
stack[i].t = stack[i-1].t;
|
||||
stack[i].val = stack[i-1].val;
|
||||
i = i-1;
|
||||
}
|
||||
|
||||
stack[i].lit = l;
|
||||
stack[i].t = t;
|
||||
stack[i].val = v;
|
||||
}
|
||||
|
||||
/* Push the constituent literals of a conjunctive goal formula in the stack. */
|
||||
|
||||
void push2goalstackCfma(satinstance sati,fma *f,int t) {
|
||||
fmalist *fs;
|
||||
switch(f->t) {
|
||||
case patom: push2goalstack(sati,PLIT(f->a),t); break;
|
||||
case natom: push2goalstack(sati,NLIT(f->a),t); break;
|
||||
case conj:
|
||||
fs = f->juncts;
|
||||
while(fs != NULL) {
|
||||
push2goalstackCfma(sati,fs->hd,t);
|
||||
fs = fs->tl;
|
||||
}
|
||||
break;
|
||||
case TRUE: break;
|
||||
default:
|
||||
assert(1==2);
|
||||
}
|
||||
}
|
||||
|
||||
/* Push a subset of the literals in a general NNF formula which are
|
||||
sufficient for making the formula true, in the stack.
|
||||
This is as in the ICAPS'11 submission.
|
||||
For conjunctions all conjuncts have to be taken.
|
||||
For disjunctions one of the disjuncts is taken. If at least one of
|
||||
the disjuncts is true or unknown, then the chosen disjunct cannot
|
||||
be a false one.
|
||||
*/
|
||||
|
||||
/* The implementation is in with a stack of sets of literals.
|
||||
The operations are
|
||||
- adding a set into the set (empty or singleton)
|
||||
- taking the union of two top stacks
|
||||
- removing the top or the second set from the stack
|
||||
- comparing the two top sets (cardinality?) for choosing a disjunct
|
||||
|
||||
tset_stack: element is the index of the first element of the set in tset_store
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
int l;
|
||||
short t;
|
||||
} storepair;
|
||||
|
||||
int stacktop;
|
||||
int storetop;
|
||||
int tset_stack[1000];
|
||||
int tset_card[1000];
|
||||
storepair tset_store[100000];
|
||||
|
||||
#define CARDTOP (storetop-tset_stack[stacktop]+1)
|
||||
#define CARD2ND (tset_stack[stacktop]-tset_stack[stacktop-1])
|
||||
|
||||
void tset_emptyset() {
|
||||
#ifdef DEBUGDISJ
|
||||
printf("tset_emptyset\n");
|
||||
#endif
|
||||
stacktop += 1;
|
||||
tset_card[stacktop] = 0;
|
||||
tset_stack[stacktop] = storetop+1;
|
||||
}
|
||||
|
||||
void tset_show() {
|
||||
#ifdef DEBUGDISJ
|
||||
int i,j;
|
||||
printf("=========================================================\n");
|
||||
for(i=0;i<=storetop+1;i++) {
|
||||
for(j=0;j<=stacktop;j++) {
|
||||
if(tset_stack[j] == i) printf("START %i (card %i)\n",j,tset_card[j]);
|
||||
}
|
||||
if(i<=storetop) {
|
||||
printf("%i: ",i); printlit(tset_store[i].l); printf("@%i\n",tset_store[i].t);
|
||||
}
|
||||
}
|
||||
printf(" =========================================================\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Add the empty set in the stack. */
|
||||
|
||||
void tset_makeempty() {
|
||||
#ifdef DEBUGDISJ
|
||||
printf("tset_makeempty\n");
|
||||
#endif
|
||||
stacktop=-1;
|
||||
storetop=-1;
|
||||
tset_emptyset(); /* Always have an empty set in the stack. */
|
||||
}
|
||||
|
||||
/* Add a singleton set into the stack. */
|
||||
|
||||
void tset_singleton(int l,int t) {
|
||||
#ifdef DEBUGDISJ
|
||||
printf("tset_singleton "); printlit(l); printf("@%i\n",t);
|
||||
#endif
|
||||
storetop = storetop+1;
|
||||
tset_store[storetop].l = l;
|
||||
tset_store[storetop].t = t;
|
||||
stacktop = stacktop+1;
|
||||
tset_stack[stacktop] = storetop;
|
||||
tset_card[stacktop] = 1;
|
||||
}
|
||||
|
||||
/* Take the union of the two top sets. */
|
||||
|
||||
void tset_union() {
|
||||
#ifdef DEBUGDISJ
|
||||
printf("tset_union\n");
|
||||
#endif
|
||||
tset_card[stacktop-1] = tset_card[stacktop-1]+tset_card[stacktop];
|
||||
stacktop = stacktop - 1;
|
||||
}
|
||||
|
||||
/* Return TRUE if top element has a smaller cardinality than the second. */
|
||||
|
||||
int tset_top_better() {
|
||||
if(tset_card[stacktop] < tset_card[stacktop-1]) return 1; else return 0;
|
||||
}
|
||||
|
||||
/* Remove the top set from the stack. */
|
||||
|
||||
void tset_top_delete() {
|
||||
#ifdef DEBUGDISJ
|
||||
printf("tset_top_delete\n");
|
||||
#endif
|
||||
storetop = storetop-tset_card[stacktop];
|
||||
stacktop = stacktop-1;
|
||||
}
|
||||
|
||||
/* Remove the second set from the stack. */
|
||||
|
||||
void tset_second_delete() {
|
||||
int i,n;
|
||||
#ifdef DEBUGDISJ
|
||||
printf("tset_second_delete\n");
|
||||
#endif
|
||||
n = tset_card[stacktop];
|
||||
/* Move the top set where the second one was. */
|
||||
for(i=0;i<n;i++) {
|
||||
tset_store[tset_stack[stacktop-1]+i] = tset_store[tset_stack[stacktop]+i];
|
||||
}
|
||||
storetop = tset_stack[stacktop-1]+n-1;
|
||||
stacktop = stacktop-1;
|
||||
tset_card[stacktop]=n;
|
||||
}
|
||||
|
||||
int traverseDfma(satinstance sati,fma *f,int t) {
|
||||
fmalist *fs;
|
||||
int have;
|
||||
|
||||
#ifdef DEBUGDISJ
|
||||
tset_show();
|
||||
#endif
|
||||
|
||||
switch(f->t) {
|
||||
/* Here we have to restrict to literals that are not FALSE ? */
|
||||
case patom:
|
||||
if(tvarfalsep(sati,f->a,t)) return 0;
|
||||
tset_singleton(PLIT(f->a),t);
|
||||
return 1;
|
||||
case natom:
|
||||
if(tvartruep(sati,f->a,t)) return 0;
|
||||
tset_singleton(NLIT(f->a),t);
|
||||
return 1;
|
||||
case conj: /* The literal sets for all conjuncts are combined. */
|
||||
tset_emptyset();
|
||||
fs = f->juncts;
|
||||
while(fs != NULL) {
|
||||
if(traverseDfma(sati,fs->hd,t) == 0) {
|
||||
tset_top_delete();
|
||||
return 0;
|
||||
}
|
||||
tset_union();
|
||||
fs = fs->tl;
|
||||
}
|
||||
return 1;
|
||||
case disj: /* The set for one of the disjuncts is chosen, others ignored. */
|
||||
// tset_emptyset(); ???????????????????
|
||||
have = 0;
|
||||
fs = f->juncts;
|
||||
while(fs != NULL) {
|
||||
if(traverseDfma(sati,fs->hd,t)) {
|
||||
if(have) {
|
||||
#ifdef DEBUGDISJ
|
||||
tset_show();
|
||||
#endif
|
||||
if(tset_top_better()) tset_second_delete(); else tset_top_delete();
|
||||
}
|
||||
have = 1;
|
||||
}
|
||||
fs = fs->tl;
|
||||
}
|
||||
return have;
|
||||
case TRUE: tset_emptyset(); return 1;
|
||||
case FALSE: return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void push2goalstackDfma(satinstance sati,fma *f,int t) {
|
||||
int i,l,t2;
|
||||
tset_makeempty();
|
||||
if(traverseDfma(sati,f,t) == 0) return;
|
||||
#ifdef DEBUGDISJ
|
||||
tset_show();
|
||||
#endif
|
||||
// if(tset_stack[stacktop]+1>storetop) printf("Not pushing anything\n");
|
||||
/* Push the literals from the traverseDfma stack into the heuristic stack. */
|
||||
for(i=tset_stack[stacktop];i<=storetop;i++) {
|
||||
l = tset_store[i].l;
|
||||
t2 = tset_store[i].t;
|
||||
#ifdef DEBUGDISJ
|
||||
printf("Pushing %i:",l); printlit(l); printf("@%i\n",t2);
|
||||
#endif
|
||||
push2goalstack(sati,l,t2);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HARDDEBUG
|
||||
void showheustack(satinstance sati) {
|
||||
int i;
|
||||
printf("STACK CONTENTS:\n");
|
||||
for(i=0;i<stackptr;i++) {
|
||||
printlit(stack[i].lit);
|
||||
printf("@%i (score %i)\n",stack[i].t,stack[i].val);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#define TMPARRAYSIZE 1000
|
||||
|
||||
void do_cpath(satinstance);
|
||||
|
||||
int weightedscore(satinstance sati,int i) {
|
||||
return sati->lits[PLIT(TVAR(plansteps[i].var,plansteps[i].t))].score + 10000-100*plansteps[i].flaws;
|
||||
}
|
||||
|
||||
/* Identify actions that are useful in reaching the goals. */
|
||||
|
||||
int do_cpath_heuristic(satinstance sati) {
|
||||
int i,j,best,besttime;
|
||||
#ifdef WEIGHTS
|
||||
int tmparray[TMPARRAYSIZE];
|
||||
#endif
|
||||
|
||||
nextround(sati);
|
||||
|
||||
Nsteps = 0;
|
||||
stackptr = 0;
|
||||
|
||||
switch(sati->heuristic_mode) {
|
||||
|
||||
case 0: /* Choose an action. */
|
||||
|
||||
if(goalisdisjunctive) {
|
||||
push2goalstackDfma(sati,goal,sati->nOfTPoints-1);
|
||||
} else {
|
||||
push2goalstackCfma(sati,goal,sati->nOfTPoints-1);
|
||||
}
|
||||
|
||||
#ifdef HARDDEBUG
|
||||
showheustack(sati);
|
||||
#endif
|
||||
|
||||
/* Find paths */
|
||||
do_cpath(sati);
|
||||
|
||||
/* Pick action. */
|
||||
|
||||
/* Only one action to choose from: return it directly. */
|
||||
if(Nsteps == 1) return PLIT(TVAR(plansteps[0].var,plansteps[0].t));
|
||||
|
||||
if(Nsteps > 0) {
|
||||
|
||||
switch(HEURactionchoice) {
|
||||
case 0: /* Choose action randomly. */
|
||||
i = random() % Nsteps;
|
||||
break;
|
||||
case 1: /* Choose the earliest possible action. */
|
||||
best = -1;
|
||||
besttime = 100000;
|
||||
for(i=0;i<Nsteps;i++) {
|
||||
if(plansteps[i].t < besttime) {
|
||||
best = i;
|
||||
besttime = plansteps[i].t;
|
||||
}
|
||||
}
|
||||
i = best;
|
||||
break;
|
||||
case 2: /* Choose action randomly, with bias to earlier. */
|
||||
j = random() % Nsteps;
|
||||
i = random() % (j+1);
|
||||
break;
|
||||
case 3: /* Choose action randomly, with bias to later. */
|
||||
j = random() % Nsteps;
|
||||
i = Nsteps-(random() % (j+1))-1;
|
||||
break;
|
||||
case 4: /* Choose action based on its weight, with ties broken
|
||||
randomly. */
|
||||
#ifdef WEIGHTS
|
||||
best = -1;
|
||||
for(i=0;i< Nsteps;i++) { /* Determine the best score. */
|
||||
int score = weightedscore(sati,i);
|
||||
if(score > best) best = score;
|
||||
}
|
||||
j = 0;
|
||||
for(i=0;i<Nsteps;i++) { /* Collect the literals with the best score. */
|
||||
if(weightedscore(sati,i) == best) {
|
||||
tmparray[j++] = i;
|
||||
ASSERT(j < 1000);
|
||||
}
|
||||
|
||||
}
|
||||
i = tmparray[random() % j];
|
||||
break;
|
||||
#else
|
||||
fprintf(stderr,"Heuristic needs WEIGHTS compiled.\n");
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
return PLIT(TVAR(plansteps[i].var,plansteps[i].t));
|
||||
// return TLIT(plansteps[i].l,plansteps[i].t);
|
||||
|
||||
}
|
||||
|
||||
sati->heuristic_mode = 1;
|
||||
sati->heuristic_time = 1;
|
||||
sati->heuristic_index = 0;
|
||||
|
||||
case 1: /* No actions needed. Do inertia. */
|
||||
|
||||
#ifdef HEURDEBUG
|
||||
printf("Doing INERTIA\n");
|
||||
#endif
|
||||
|
||||
while(sati->heuristic_time < sati->nOfTPoints) {
|
||||
|
||||
i = sati->heuristic_index;
|
||||
j = sati->heuristic_time;
|
||||
|
||||
if(i+1 == sati->nOfSVars) {
|
||||
sati->heuristic_index = 0;
|
||||
sati->heuristic_time += 1;
|
||||
} else {
|
||||
sati->heuristic_index += 1;
|
||||
}
|
||||
|
||||
if(tvarunsetp(sati,i,j)) {
|
||||
if(tvartruep(sati,i,j-1)) return PLIT(TVAR(i,j));
|
||||
else return NLIT(TVAR(i,j));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sati->heuristic_mode = 2;
|
||||
sati->heuristic_time = 0;
|
||||
sati->heuristic_index = 0;
|
||||
|
||||
case 2: /* All state variables have a value. Set actions to FALSE. */
|
||||
|
||||
while(sati->heuristic_time < sati->nOfTPoints-1) {
|
||||
|
||||
i = sati->heuristic_index;
|
||||
j = sati->heuristic_time;
|
||||
|
||||
if(i+1 == sati->nOfActions) {
|
||||
sati->heuristic_index = 0;
|
||||
sati->heuristic_time += 1;
|
||||
} else {
|
||||
sati->heuristic_index += 1;
|
||||
}
|
||||
|
||||
if(tvarunsetp(sati,ACTVAR(i),j)) return NLIT(TVAR(ACTVAR(i),j));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
int fmavalue(satinstance sati,fma *f,int t) {
|
||||
fmalist *juncts;
|
||||
switch(f->t) {
|
||||
case patom: if(!tvarfalsep(sati,f->a,t)) return 1; else return 0;
|
||||
case natom: if(!tvartruep(sati,f->a,t)) return 1; else return 0;
|
||||
case disj:
|
||||
juncts = f->juncts;
|
||||
while(juncts != NULL) {
|
||||
if(fmavalue(sati,juncts->hd,t) != 0) return 1;
|
||||
juncts = juncts->tl;
|
||||
}
|
||||
return 0;
|
||||
case conj:
|
||||
juncts = f->juncts;
|
||||
while(juncts != NULL) {
|
||||
if(fmavalue(sati,juncts->hd,t) == 0) return 0;
|
||||
juncts = juncts->tl;
|
||||
}
|
||||
return 1;
|
||||
case TRUE: return 1;
|
||||
case FALSE: return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Estimate the value for an action */
|
||||
|
||||
int actionvalue(satinstance sati,int var,int t,fma *precondition,int disjunctive) {
|
||||
int i;
|
||||
int val;
|
||||
switch(HEURops) {
|
||||
case 1: /* Evaluate 'constrainedness' of action */
|
||||
/* How many steps later can this action be taken? */
|
||||
val = 0;
|
||||
while(t+1 < sati->nOfTPoints-1 && !tvarfalsep(sati,var,t+1)) {
|
||||
t = t+1;
|
||||
val = val + 1;
|
||||
}
|
||||
return val;
|
||||
case 2: /* Evaluate 'constrainedness' of action */
|
||||
/* How many steps later can this action be taken? */
|
||||
val = 0;
|
||||
while(t+1 < sati->nOfTPoints-1 && !tvarfalsep(sati,var,t+1)) {
|
||||
t = t+1;
|
||||
val = val + 1;
|
||||
}
|
||||
return 1000-val;
|
||||
case 3: /* Evaluate 'constrainedness' of precondition */
|
||||
/* How many steps later can the precondition be true? */
|
||||
val = 0;
|
||||
while(t+1 < sati->nOfTPoints && fmavalue(sati,precondition,t+1) != 0) {
|
||||
t = t+1;
|
||||
val = val + 1;
|
||||
}
|
||||
return val;
|
||||
case 4: /* Evaluate 'constrainedness' of precondition */
|
||||
/* How many steps later can the precondition be true? */
|
||||
val = 0;
|
||||
while(t+1 < sati->nOfTPoints && fmavalue(sati,precondition,t+1) != 0) {
|
||||
t = t+1;
|
||||
val = val + 1;
|
||||
}
|
||||
return 1000-val;
|
||||
case 5:
|
||||
/* How many steps earlier can the precondition be true? */
|
||||
val = 0;
|
||||
while(t-1 >= 0 && fmavalue(sati,precondition,t-1) != 0) {
|
||||
t = t-1;
|
||||
val = val + 1;
|
||||
}
|
||||
return val;
|
||||
case 6:
|
||||
/* How many steps earlier can the precondition be true? */
|
||||
val = 0;
|
||||
while(t-1 >= 0 && fmavalue(sati,precondition,t-1) != 0) {
|
||||
t = t-1;
|
||||
val = val + 1;
|
||||
}
|
||||
return 1000-val;
|
||||
case 7:
|
||||
/* How many later suggested actions the action disables/affects. */
|
||||
val = 0;
|
||||
for(i=0;i<Nsteps;i++) {
|
||||
if((plansteps[i].t > t) && (actaffects(var,plansteps[i].var))) {
|
||||
val = val + 1;
|
||||
}
|
||||
}
|
||||
// printf("{%i}",val);
|
||||
return 1000-val;
|
||||
default: assert(2==7);
|
||||
}
|
||||
}
|
||||
|
||||
/* Go through actions at time point t-1 to find one that could
|
||||
make literal l true at t. "Could" means: l occurs as a conditional
|
||||
or unconditional effect, and we don't care about the condition.
|
||||
|
||||
This is based on the following parameters (given on command line):
|
||||
HEURtime: which time to consider, 0 = earliest, 1 = latest, 2 = all
|
||||
HEURops: which operator to consider 0 = first (arbitrary), 1 = all
|
||||
HEURchoice: which action@time to choose, 0 = random, 1 = weight
|
||||
*/
|
||||
|
||||
/* Choose an action at t1-1 that can make l@t TRUE. The action is returned
|
||||
in var,t. */
|
||||
|
||||
void supports(satinstance sati,int t0,int t1,int l,int *var,int *t,fma **precondition,int *disjunctive) {
|
||||
compactCEstruct *ptr;
|
||||
int bestvalue,value;
|
||||
int bestvar,bestt,bestdisjunctive;
|
||||
fma *bestprecondition;
|
||||
|
||||
if(HEURops == 0) { /* Return the "first" (arbitrary) action. */
|
||||
|
||||
for(ptr=cCEs[l];ptr->var != -1;ptr++) { /* All ways of making l true. */
|
||||
if(!tvarfalsep(sati,ptr->var,t1-1)) { /* Is it applicable? */
|
||||
#ifdef HARDDEBUG
|
||||
printf("Add ACTION %i:",ptr->var); printUvar(ptr->var); printf("@%i\n",t1-1);
|
||||
#endif
|
||||
*var = ptr->var;
|
||||
*t = t1-1;
|
||||
*precondition = ptr->condition;
|
||||
*disjunctive = ptr->disjunctive;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
assert(1==2);
|
||||
}
|
||||
|
||||
bestvar = -1;
|
||||
|
||||
for(ptr=cCEs[l];ptr->var != -1;ptr++) { /* All ways of making l true. */
|
||||
if(!tvarfalsep(sati,ptr->var,t1-1)) { /* Is it applicable? */
|
||||
#ifdef HARDDEBUG
|
||||
printf("Consider ACTION %i:",ptr->var); printUvar(ptr->var); printf("@%i\n",t1-1);
|
||||
#endif
|
||||
if(bestvar == -1) {
|
||||
bestvar = ptr->var;
|
||||
bestt = t1-1;
|
||||
bestprecondition = ptr->condition;
|
||||
bestdisjunctive = ptr->disjunctive;
|
||||
bestvalue = actionvalue(sati,ptr->var,t1-1,ptr->condition,ptr->disjunctive);
|
||||
} else {
|
||||
value = actionvalue(sati,ptr->var,t1-1,ptr->condition,ptr->disjunctive);
|
||||
if(value > bestvalue) {
|
||||
bestvar = ptr->var;
|
||||
bestt = t1-1;
|
||||
bestprecondition = ptr->condition;
|
||||
bestdisjunctive = ptr->disjunctive;
|
||||
bestvalue = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert(bestvar != -1);
|
||||
|
||||
#ifdef DECDEBUG
|
||||
printf("Best action: ");
|
||||
printUvar(bestvar);
|
||||
printf("@%i for ",bestt);
|
||||
printlit(l);
|
||||
printf(" has value %i.\n",bestvalue);
|
||||
#endif
|
||||
|
||||
*var = bestvar;
|
||||
*t = bestt;
|
||||
*precondition = bestprecondition;
|
||||
*disjunctive = bestdisjunctive;
|
||||
}
|
||||
|
||||
|
||||
/* Is some action op actually making l true at t-1? (= op assigned TRUE?) */
|
||||
|
||||
int litmadetrue(satinstance sati,int l,int t,fma **precondition,int *disjunctive) {
|
||||
int i;
|
||||
|
||||
if(!littruep(sati,litwithtime(sati,l,t))) return -1; /* l@t is not even true: no action! */
|
||||
|
||||
for(i=0;cCEs[l][i].var != -1;i++) { /* All ways of making l@t-1 true. */
|
||||
if(tvartruep(sati,cCEs[l][i].var,t-1)) {
|
||||
*precondition = cCEs[l][i].condition;
|
||||
*disjunctive = cCEs[l][i].disjunctive;
|
||||
return cCEs[l][i].var;
|
||||
}
|
||||
}
|
||||
|
||||
return -1; /* l@t-1 not made true. */
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
/*** Heuristic: ***/
|
||||
/*** Find an unfulfilled (sub)goal and fulfill it at the earliest ***/
|
||||
/*** possible time point. ***/
|
||||
/*** ***/
|
||||
/***********************************************************************/
|
||||
|
||||
#define noPRUNEfromGOAL
|
||||
#define noPRUNEtoGOAL
|
||||
|
||||
void do_cpath(satinstance sati) {
|
||||
int l,t,t1;
|
||||
int j,var,isthere;
|
||||
int suggestedactionsfound;
|
||||
int depthlimitHIGH;
|
||||
fma *precondition;
|
||||
int disjunctive;
|
||||
|
||||
depthlimitHIGH = -1;
|
||||
suggestedactionsfound = 0;
|
||||
|
||||
while(stackptr > 0) {
|
||||
|
||||
/* Pop literal-time pair from the stack. */
|
||||
l = stack[stackptr-1].lit;
|
||||
t = stack[--stackptr].t;
|
||||
|
||||
#ifdef PRUNEtoGOAL
|
||||
if(HEURactiondepthlimit && suggestedactionsfound && t >= depthlimitHIGH)
|
||||
return;
|
||||
#endif
|
||||
|
||||
#ifdef HEURDEBUG
|
||||
printf("Find action for goal "); printlit(l); printf("@%i.\n",t);
|
||||
#endif
|
||||
|
||||
/* Starting from last time point, find last time t such that either
|
||||
1) an action op@t-1 makes l@t TRUE, or
|
||||
2) l@t-1 is FALSE and l@t is TRUE or UNASSIGNED.
|
||||
*/
|
||||
isthere = 0;
|
||||
var = -1;
|
||||
|
||||
for(j=t;j>0;j--) {
|
||||
var = litmadetrue(sati,l,j,&precondition,&disjunctive);
|
||||
if(var != -1) {
|
||||
isthere = 1;
|
||||
t1 = j-1;
|
||||
break;
|
||||
}
|
||||
|
||||
if(litfalsep(sati,litwithtime(sati,l,j-1))) break;
|
||||
}
|
||||
|
||||
if(j == 0) { /* Literal is true at time 0. */
|
||||
#ifdef HEURDEBUG
|
||||
printf("(true in the initial state.)\n");
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Literal is last false at time point j-1. */
|
||||
|
||||
if(var == -1) { /* Choose an action that turns l true between j-1 and j. */
|
||||
supports(sati,t,j,l,&var,&t1,&precondition,&disjunctive);
|
||||
/* The following assertions cannot be false because
|
||||
there must be an action that could make l true at t1 (i.e. is not FALSE).
|
||||
If there were not, the frame action (-l & l) -> ... would
|
||||
contradict Ass1 and Ass2.
|
||||
*/
|
||||
ASSERT(var != 0);
|
||||
ASSERT(precondition->t != -1);
|
||||
ASSERT(tlitfalsep(sati,l,j-1));
|
||||
ASSERT(!tlitfalsep(sati,l,j));
|
||||
}
|
||||
|
||||
if(seenp(sati,TVAR(var,t1))) continue; /* Operator already processed once. */
|
||||
|
||||
/* Don't go back to top-level goals. */
|
||||
|
||||
#ifndef PRUNEtoGOAL
|
||||
if(HEURactiondepthlimit && suggestedactionsfound && t1 >= depthlimitHIGH)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if(!isthere) { /* Add the variable to the list of candidate decisions. */
|
||||
suggestedactionsfound += 1;
|
||||
plansteps[Nsteps].var = var;
|
||||
plansteps[Nsteps].t = t1;
|
||||
plansteps[Nsteps].flaws = 0;
|
||||
if(HEURops == 7) {
|
||||
for(j=0;j<Nsteps;j++) {
|
||||
if(actaffects(var,plansteps[j].var)) plansteps[Nsteps].flaws += 1;
|
||||
}
|
||||
}
|
||||
plansteps[Nsteps++].l = l;
|
||||
|
||||
#ifdef HEURDEBUG
|
||||
printf("Chose action ");
|
||||
printUvar(var);
|
||||
printf(" to make literal true @%i.\n",j);
|
||||
#endif
|
||||
|
||||
#ifdef PRUNEfromGOAL
|
||||
if(suggestedactionsfound == 1) depthlimitHIGH = t;
|
||||
#else
|
||||
if(suggestedactionsfound == 1) depthlimitHIGH = t1;
|
||||
#endif
|
||||
}
|
||||
|
||||
ASSERT(Nsteps < MAXPLANSTEPS);
|
||||
|
||||
if(suggestedactionsfound >= HEURactions) return;
|
||||
|
||||
#ifdef HARDDEBUG
|
||||
printf(" Push preconditions of %i:",var); printUvar(var); printf("@%i into the stack (%i).\n",t1,isthere);
|
||||
#endif
|
||||
|
||||
if(t1 > 0) { /* Push preconditions in the stack. */
|
||||
if(disjunctive == 0) {
|
||||
push2goalstackCfma(sati,precondition,t1);
|
||||
} else {
|
||||
push2goalstackDfma(sati,precondition,t1);
|
||||
}
|
||||
#ifdef HARDDEBUG
|
||||
showheustack(sati);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
265
interface.h
Normal file
265
interface.h
Normal file
@ -0,0 +1,265 @@
|
||||
|
||||
/* 2012 (C) Jussi Rintanen, jrintanen.jr@gmail.com */
|
||||
|
||||
#if defined(__LP64__)
|
||||
#define PTRINT long
|
||||
#else
|
||||
#define PTRINT int
|
||||
#endif
|
||||
|
||||
typedef struct _thread {
|
||||
int cround; /* Counter which is incremented for new conflict clauses */
|
||||
int maxwasseen;
|
||||
int *wasseen; /* Counter when literal was last encountered */
|
||||
#define MAXCCLENGTH 10000000
|
||||
int cc[MAXCCLENGTH]; /* Conflict clause which is being constructed */
|
||||
#ifndef FUIP
|
||||
int stck[MAXCCLENGTH]; /* The stack used during computing the conflict clause */
|
||||
#endif
|
||||
|
||||
} thread;
|
||||
|
||||
thread *threads;
|
||||
|
||||
#define SVAR(v) (v)
|
||||
#define ACTVAR(a) ((a)+(sati->nOfSVars))
|
||||
#define TVAR(v,t) ((v)+(t)*(sati->nOfVarsPerTime))
|
||||
#define TLIT(l,t) ((l)+2*(t)*(sati->nOfVarsPerTime))
|
||||
#define TACT(a,t) ((ACTVAR(a))+(t)*(sati->nOfVarsPerTime))
|
||||
|
||||
typedef struct _nintlist { int hd; struct _nintlist *tl; } nintlist;
|
||||
|
||||
|
||||
/*********************** VARIABLES *******************/
|
||||
|
||||
#define STATUSTYPE char
|
||||
|
||||
/************* LITERALS & WATCH LISTS *****************/
|
||||
|
||||
/* The watch list has the watch list EMBEDDED in the clause data structure
|
||||
(Biere et al. ???)
|
||||
*/
|
||||
|
||||
#define LITWATCHES(l) (sati->lits[(l)].watches)
|
||||
|
||||
typedef struct _literal {
|
||||
int *watches;
|
||||
#ifdef WEIGHTS
|
||||
short score; /* Scores for choosing decision variables */
|
||||
#endif
|
||||
} literal;
|
||||
|
||||
/********************** HEAP *********************/
|
||||
|
||||
/* Heap for keeping track of the highest score variables.
|
||||
Each element in the heap has two components:
|
||||
k: key, i.e. the index of the variable
|
||||
v: value, i.e. the current VSIDS score/weight
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
int k;
|
||||
short v;
|
||||
} pair;
|
||||
|
||||
typedef struct _heap {
|
||||
int els;
|
||||
int maxels;
|
||||
pair *array;
|
||||
} *heap;
|
||||
|
||||
|
||||
/******************* SAT INSTANCE *******************/
|
||||
|
||||
#define REASONDLEVEL
|
||||
|
||||
#ifdef REASONDLEVEL
|
||||
typedef struct {
|
||||
PTRINT reason;
|
||||
int dlevel;
|
||||
} RD;
|
||||
#endif
|
||||
|
||||
typedef struct _satinstance {
|
||||
short id; /* Unique integer id for the instance */
|
||||
int thread; /* The thread this is run in. */
|
||||
|
||||
short value; /* The truth-value of the instance, -1 = unknown */
|
||||
int nOfVars; /* Number of propositional variables */
|
||||
int nOfVarsPerTime; /* Number of vars per time point */
|
||||
short nOfTPoints; /* Number of time points */
|
||||
|
||||
nintlist **l2its; /* Array for 2-literal clauses (for all time points), non-changing */
|
||||
int **al2its; /* Array for 2-literal clauses (for all time points), non-changing */
|
||||
|
||||
literal *lits; /* Data structure for literals */
|
||||
|
||||
int *declevels;
|
||||
#ifdef COSTS
|
||||
int declevelscost;
|
||||
#endif
|
||||
|
||||
#if defined REPRTWO || defined REPRFOUR
|
||||
#define VALTYPE int
|
||||
#else
|
||||
#define VALTYPE char
|
||||
#endif
|
||||
|
||||
VALTYPE *variableval;
|
||||
|
||||
int dlevel; /* Current decision level of the SAT instance. */
|
||||
|
||||
int decisions; /* How many decision made */
|
||||
int conflicts; /* How many conflicts */
|
||||
int decaysteps; /* Counter for variable weight decays */
|
||||
|
||||
int conflicttype2lit;
|
||||
int *conflictclause; /* Clause that was falsified */
|
||||
int conflictl1; /* Following four set when empty clause derived. */
|
||||
int conflictl2;
|
||||
|
||||
#ifndef MULTICORE
|
||||
int cc[MAXCCLENGTH]; /* Conflict clause which is being constructed */
|
||||
#ifndef FUIP
|
||||
int stck[MAXCCLENGTH]; /* The stack used during computing the conflict clause */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef VSIDS
|
||||
STATUSTYPE *variablestatus;
|
||||
/* These are the status bits.
|
||||
bit 0 is phase there?
|
||||
bit 1 phase
|
||||
bit 2 dirty? (whether inferred with the goal clauses)
|
||||
*/
|
||||
#define VARSTATUS(v) (sati->variablestatus[(v)])
|
||||
#endif
|
||||
|
||||
#ifndef REASONDLEVEL
|
||||
|
||||
PTRINT *variablereason;
|
||||
int *variabledlevel;
|
||||
#define LITREASON(l) (sati->variablereason[VAR(l)])
|
||||
#define LITDLEVEL(l) (sati->variabledlevel[VAR(l)])
|
||||
|
||||
#else
|
||||
|
||||
RD *variablerd;
|
||||
|
||||
#define LITREASON(l) (sati->variablerd[VAR(l)].reason)
|
||||
#define LITDLEVEL(l) (sati->variablerd[VAR(l)].dlevel)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef VSIDS
|
||||
int *hindex; /* Index of each variable in the heap. */
|
||||
heap scoreheap; /* Literals ordered according to their score */
|
||||
#endif
|
||||
|
||||
int *initialunittable; /* Table for the unit clauses in the input */
|
||||
int maxinitialunits; /* The size of the table */
|
||||
int initialunits; /* Number of unit clauses in the table */
|
||||
|
||||
int *unitstack; /* Stack of assignments made */
|
||||
int endunitstack,startunitstack; /* Unprocessed part of the stack */
|
||||
|
||||
int nOfSVars; /* Planning: number of state variables (per time) */
|
||||
int nOfActions; /* Planning number of actions (per time) */
|
||||
|
||||
int complete; /* true if all input clauses have been added */
|
||||
int notcalledbefore; /* true if solve0 not called yet. */
|
||||
|
||||
/* Fields for the heuristics */
|
||||
int pheuristic; /* Which planning-based heuristic to use. */
|
||||
int heuristic; /* Which branching heuristic to use. */
|
||||
/* Unit clauses that have been learned */
|
||||
#define MAXUCC 10000
|
||||
int NofUCClauses;
|
||||
int UCC[MAXUCC];
|
||||
|
||||
/* Variables for the planning heuristic */
|
||||
int heuristic_mode; /* This is 0 for actions, 1 for inertia, 2 for noops. */
|
||||
int heuristic_time; /* The next two are for inertia and noops. */
|
||||
int heuristic_index;
|
||||
#ifdef COSTS
|
||||
int costbound; /* Cost bound */
|
||||
int currentcost; /* Cost of current (partial) assignment */
|
||||
int *costs; /* Costs all (untimed) state variables */
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef GOALWEIGHTS
|
||||
int *supportsg; /* Which subgoal action supports. */
|
||||
int *supportsa; /* Which action (previous decision) action supports. */
|
||||
#endif
|
||||
|
||||
#ifdef LBD
|
||||
int LBDcounter;
|
||||
int *LBDflag;
|
||||
#endif
|
||||
|
||||
} *satinstance;
|
||||
|
||||
typedef enum { InitC, FinalC, TransC } clausetype;
|
||||
|
||||
float estimateinstancesize(int,int,int);
|
||||
|
||||
satinstance newinstance(int,int,int,int,int);
|
||||
void freeinstance(satinstance);
|
||||
|
||||
void addnewclause(satinstance,int,clausetype); /* Number of literals in the clause (> 2) */
|
||||
void addliteral(satinstance,int,int); /* Put literal to the given loc in the clause */
|
||||
void finishclause(satinstance); /* Finish adding the clause */
|
||||
|
||||
int add1clause(satinstance,int,clausetype); /* Add a 1-literal clause */
|
||||
void add2clause(satinstance,int,int,clausetype); /* Add a 2-literal clause */
|
||||
|
||||
void instancecomplete();
|
||||
|
||||
void planningparameters(satinstance,int,int);
|
||||
void setheuristic(satinstance,int);
|
||||
void setpheuristic(satinstance,int);
|
||||
|
||||
int solve(satinstance);
|
||||
int solve0(satinstance,int,int);
|
||||
|
||||
int noT2clauses;
|
||||
|
||||
void addtimedvarcost(satinstance,int,int);
|
||||
|
||||
int varvalue(satinstance,int);
|
||||
int vartruep(satinstance,int);
|
||||
int tvarvalue(satinstance,int,int);
|
||||
int tvarvar(satinstance,int);
|
||||
int tvartime(satinstance,int);
|
||||
|
||||
int VALUE(int);
|
||||
int NEG(int);
|
||||
int VAR(int);
|
||||
int PLIT(int);
|
||||
int NLIT(int);
|
||||
int LIT(int);
|
||||
|
||||
#define UNASS -1
|
||||
|
||||
int propagate(satinstance);
|
||||
|
||||
void init_clausesets(int);
|
||||
|
||||
double allocatedbyCL;
|
||||
float memoryused();
|
||||
|
||||
int flagShortCutHorizon;
|
||||
|
||||
void shortcuts(satinstance sati);
|
||||
|
||||
typedef struct _shortcutclause {
|
||||
int l1,l2,tdiff;
|
||||
} shortcutclause;
|
||||
|
||||
shortcutclause *shortcutclauses;
|
||||
int nofshortcutclauses;
|
||||
int maxshortcutclauses;
|
||||
|
||||
void nextround(satinstance sati);
|
196
intsets.c
Normal file
196
intsets.c
Normal file
@ -0,0 +1,196 @@
|
||||
|
||||
/* 2012 (C) Jussi Rintanen */
|
||||
|
||||
#include "intsets.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int *fieldaddress(intset s) {
|
||||
return ((int *)s)+3;
|
||||
}
|
||||
|
||||
/* BUG? There was a segmentation fault caused by the assingment to s->maxEls
|
||||
below. It is not obvious whether it was the call to statmalloc that
|
||||
has now been replaced by malloc, or something else. */
|
||||
|
||||
intset IScreateSize(int size) {
|
||||
intset s;
|
||||
s = (intset)malloc(sizeof(struct _intset));
|
||||
// s = (intset)malloc(sizeof(struct _intset) + size * sizeof(int));
|
||||
s->maxEls = size;
|
||||
s->nOfEls = 0;
|
||||
// s->elements = (int *)statmalloc(602,s->maxEls * sizeof(int));
|
||||
s->elements = (int *)malloc(s->maxEls * sizeof(int));
|
||||
// s->elements = fieldaddress(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
intset IScreate() {
|
||||
return IScreateSize(30);
|
||||
}
|
||||
|
||||
int IScard(intset s) {
|
||||
return s->nOfEls;
|
||||
}
|
||||
|
||||
int ISemptyp(intset s) {
|
||||
return s->nOfEls == 0;
|
||||
}
|
||||
|
||||
void ISmakeempty(intset s) {
|
||||
s->nOfEls = 0;
|
||||
}
|
||||
|
||||
int *ISrealloc(intset s) {
|
||||
// if(s->elements != fieldaddress(s)) {
|
||||
s->elements = (int *)realloc(s->elements,s->maxEls * sizeof(int));
|
||||
// } else {
|
||||
// printf("Reallocated.\n");
|
||||
// s->elements = (int *)malloc(s->maxEls * sizeof(int));
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
void ISinsert(int i,intset s) {
|
||||
int j;
|
||||
for(j=0;j<s->nOfEls;j++) {
|
||||
if(s->elements[j] == i) return;
|
||||
}
|
||||
if(s->nOfEls == s->maxEls) {
|
||||
s->maxEls = s->maxEls + 100;
|
||||
ISrealloc(s);
|
||||
}
|
||||
s->nOfEls += 1;
|
||||
s->elements[s->nOfEls-1] = i;
|
||||
// if(s->nOfEls > maxcard) maxcard = s->nOfEls;
|
||||
}
|
||||
|
||||
/* Insert new element that you know is new, without checking duplicates. */
|
||||
|
||||
void ISinsertNODUP(int i,intset s) {
|
||||
if(s->nOfEls == s->maxEls) {
|
||||
s->maxEls = s->maxEls + 100;
|
||||
ISrealloc(s);
|
||||
}
|
||||
s->nOfEls += 1;
|
||||
s->elements[s->nOfEls-1] = i;
|
||||
// if(s->nOfEls > maxcard) maxcard = s->nOfEls;
|
||||
}
|
||||
|
||||
void ISremove(int i,intset s) {
|
||||
int j;
|
||||
for(j=0;j<s->nOfEls;j++) {
|
||||
if(s->elements[j] == i) {
|
||||
s->elements[j] = s->elements[s->nOfEls-1];
|
||||
s->nOfEls -= 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ISremoveSet(intset s1,intset s2) {
|
||||
int i;
|
||||
for(i=0;i<s1->nOfEls;i++) ISremove(s1->elements[i],s2);
|
||||
}
|
||||
|
||||
void ISaddelements(intset s1,intset s2) {
|
||||
int i;
|
||||
for(i=0;i<s1->nOfEls;i++) {
|
||||
ISinsert(s1->elements[i],s2);
|
||||
}
|
||||
}
|
||||
|
||||
int ISintersectwith(intset s1,intset s2) {
|
||||
int i;
|
||||
int change;
|
||||
change = 0;
|
||||
i = 0;
|
||||
while(i<s1->nOfEls) {
|
||||
if(ISmember(s1->elements[i],s2)) {
|
||||
i += 1;
|
||||
} else {
|
||||
change = 1;
|
||||
s1->elements[i] = s1->elements[s1->nOfEls-1];
|
||||
s1->nOfEls -= 1;
|
||||
}
|
||||
}
|
||||
return change;
|
||||
}
|
||||
|
||||
/* Compute the intersection of first two sets and put it into the third */
|
||||
|
||||
void ISintersectto(intset s1,intset s2,intset s3) {
|
||||
int i;
|
||||
ISmakeempty(s3);
|
||||
for(i=0;i<s1->nOfEls;i++) {
|
||||
if(ISmember(s1->elements[i],s2)) ISinsert(s1->elements[i],s3);
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute the difference of first two sets and put it into the third */
|
||||
|
||||
void ISdifferenceto(intset s1,intset s2,intset s3) {
|
||||
int i;
|
||||
ISmakeempty(s3);
|
||||
for(i=0;i<s1->nOfEls;i++) {
|
||||
if(!ISmember(s1->elements[i],s2)) ISinsertNODUP(s1->elements[i],s3);
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy set to another */
|
||||
|
||||
void IScopyto(intset s1,intset s2) {
|
||||
int i;
|
||||
s2->nOfEls = s1->nOfEls;
|
||||
if(s1->nOfEls >= s2->maxEls) {
|
||||
s2->maxEls = s1->nOfEls + 10;
|
||||
ISrealloc(s2);
|
||||
}
|
||||
for(i=0;i<s1->nOfEls;i++) {
|
||||
s2->elements[i] = s1->elements[i];
|
||||
}
|
||||
}
|
||||
|
||||
int ISmember(int i,intset s) {
|
||||
int j;
|
||||
for(j=0;j<s->nOfEls;j++) {
|
||||
if(s->elements[j] == i) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ISfree(intset s) {
|
||||
free(s->elements);
|
||||
free(s);
|
||||
}
|
||||
|
||||
void ISprint(intset s) {
|
||||
int i;
|
||||
int first;
|
||||
first = 1;
|
||||
ITstart(s);
|
||||
while(ITnext(&i)) {
|
||||
if(first) printf(" ");
|
||||
printf("%i",i);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Iterator for going through the elements of a list */
|
||||
|
||||
int *ITptr;
|
||||
int ITcounter;
|
||||
|
||||
void ITstart(intset s) {
|
||||
ITcounter = s->nOfEls;
|
||||
ITptr = s->elements;
|
||||
}
|
||||
|
||||
int ITnext(int *i) {
|
||||
if(ITcounter <= 0) return 0;
|
||||
ITcounter -= 1;
|
||||
*i = *(ITptr++);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void printgraph(char *n,intset s) { }
|
75
intsets.h
Normal file
75
intsets.h
Normal file
@ -0,0 +1,75 @@
|
||||
|
||||
/* 2012 (C) Jussi Rintanen */
|
||||
|
||||
#define AATREEnot
|
||||
#define AADIRECTnot
|
||||
|
||||
#ifndef AATREE
|
||||
#ifndef AADIRECT
|
||||
typedef struct _intset {
|
||||
int maxEls;
|
||||
int nOfEls;
|
||||
int *elements;
|
||||
} *intset;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef AATREE
|
||||
typedef struct _intsetel {
|
||||
int el;
|
||||
short level;
|
||||
short c1;
|
||||
short c2;
|
||||
} intsetel;
|
||||
|
||||
typedef struct _intset {
|
||||
int root;
|
||||
int maxEls;
|
||||
int nOfEls;
|
||||
int lastEl;
|
||||
int freed;
|
||||
intsetel *elements;
|
||||
} *intset;
|
||||
#endif
|
||||
|
||||
#ifdef AADIRECT
|
||||
typedef struct _intsetel {
|
||||
int el;
|
||||
short level;
|
||||
struct _intsetel *c1;
|
||||
struct _intsetel *c2;
|
||||
} *intsetel;
|
||||
|
||||
typedef struct _intset {
|
||||
intsetel root;
|
||||
int nOfEls;
|
||||
} *intset;
|
||||
#endif
|
||||
|
||||
intset IScreate();
|
||||
intset IScreateSize(int);
|
||||
int IScard(intset);
|
||||
int ISemptyp(intset);
|
||||
void ISmakeempty();
|
||||
void ISinsertNODUP(int,intset);
|
||||
void ISinsert(int,intset);
|
||||
void ISremove(int,intset);
|
||||
void ISremoveSet(intset,intset);
|
||||
void ISaddelements(intset,intset);
|
||||
/* int ISintersectwith(intset,intset); */
|
||||
/* void ISintersectto(intset,intset,intset); */
|
||||
void ISdifferenceto(intset,intset,intset);
|
||||
void ISadddifferenceto(intset,intset,intset);
|
||||
void IScopyto(intset,intset);
|
||||
int ISmember(int,intset);
|
||||
|
||||
void ISprint(intset);
|
||||
|
||||
/* Iterator */
|
||||
|
||||
void ITstart(intset);
|
||||
int ITnext(int *);
|
||||
|
||||
/* Debugging */
|
||||
|
||||
void printgraph(char *,intset);
|
605
invariants.c
Normal file
605
invariants.c
Normal file
@ -0,0 +1,605 @@
|
||||
|
||||
/* 2012 (C) Jussi Rintanen jrintanen.jr@gmail.com */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "asyntax.h"
|
||||
#include "intsets.h"
|
||||
#include "ordintsets.h"
|
||||
#include "operators.h"
|
||||
#include "tables.h"
|
||||
#include "invariants.h"
|
||||
#include "main.h"
|
||||
|
||||
#define noDEBUG
|
||||
|
||||
|
||||
/* Local copies (for inlining) of intsets.c functions */
|
||||
|
||||
int *iITptr;
|
||||
int iITcounter;
|
||||
|
||||
inline void iITstart(intset s) {
|
||||
iITcounter = s->nOfEls;
|
||||
iITptr = s->elements;
|
||||
}
|
||||
|
||||
inline int iITnext(int *i) {
|
||||
if(iITcounter <= 0) return 0;
|
||||
iITcounter -= 1;
|
||||
*i = *(iITptr++);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
|
||||
void printlitlist(intset s) {
|
||||
int i;
|
||||
iITstart(s);
|
||||
while(iITnext(&i)) {
|
||||
if(i&1) printf(" -");
|
||||
else printf(" ");
|
||||
printatomi(feVAR(i));
|
||||
}
|
||||
}
|
||||
|
||||
void showInvariants() {
|
||||
int i,cntpersistent;
|
||||
|
||||
cntpersistent = 0;
|
||||
printf("PERSISTENT LITERALS:"); fflush(stdout);
|
||||
for(i=0;i<nOfAtoms;i++) {
|
||||
if(onelits[i] == 1) { printf(" "); printatomi(i); }
|
||||
else if(onelits[i] == 0) { printf(" -"); printatomi(i); }
|
||||
if(onelits[i] != -1) cntpersistent += 1;
|
||||
}
|
||||
printf("\nThere are %i persistent literals (out of total of %i literals).\n",cntpersistent,nOfAtoms);
|
||||
|
||||
printf("Invariants:\n");
|
||||
|
||||
for(i=0;i<nOfAtoms;i++) {
|
||||
printatomi(i); printf(" OR:");
|
||||
printlitlist(twolits[fePLIT(i)]);
|
||||
printf("\n");
|
||||
|
||||
printf("-"); printatomi(i); printf(" OR:");
|
||||
printlitlist(twolits[feNLIT(i)]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void showInvariantsBrief() {
|
||||
int i;
|
||||
printf("True literals:");
|
||||
for(i=0;i<nOfAtoms;i++) {
|
||||
if(onelits[i] == 1) { printf(" "); printatomi(i); }
|
||||
else if(onelits[i] == 0) { printf(" -"); printatomi(i); }
|
||||
}
|
||||
printf("\nTrue 2-literal clauses:\n");
|
||||
|
||||
for(i=0;i<nOfAtoms;i++) {
|
||||
|
||||
printatomi(i); printf(" OR ");
|
||||
printlitlist(twolits[fePLIT(i)]);
|
||||
printf("\n");
|
||||
|
||||
printf("-"); printatomi(i); printf(" OR ");
|
||||
printlitlist(twolits[feNLIT(i)]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//#define iITnext ITnext
|
||||
//#define iITstart ITstart
|
||||
|
||||
int *onelits;
|
||||
intset *twolits;
|
||||
|
||||
/* Preprocessing for operators:
|
||||
For each operator and conditional effect compute
|
||||
|
||||
A. list of literals guaranteed to be true before
|
||||
the conditional effect is executed
|
||||
|
||||
B. list of literals guaranteed to be true after
|
||||
|
||||
Literals derived from the precondition are included in lists A.
|
||||
|
||||
If there are unconditional effects (condition TRUE) then
|
||||
these are included in all lists B.
|
||||
|
||||
Literals in list A that are guaranteed not to be falsified
|
||||
by a simultaneous conditional effect are included in B.
|
||||
|
||||
*/
|
||||
|
||||
typedef struct _llist {
|
||||
intset before;
|
||||
intset after;
|
||||
} llist;
|
||||
|
||||
/* Compute effect literals consisting of the positive, the negative
|
||||
and the ones in a conditional effect with an always-true condition. */
|
||||
|
||||
void addeffectlitsL(int *lits,eff *current,eff *all,intset s) {
|
||||
int *ptr;
|
||||
while(*lits != -1) { ISinsert(*lits,s); lits = lits + 1; }
|
||||
while(all != NULL) {
|
||||
if(all->condition->t == TRUE && all != current) {
|
||||
ptr = all->effectlits;
|
||||
while(*ptr != -1) {
|
||||
ISinsert(*ptr,s);
|
||||
ptr = ptr+1;
|
||||
}
|
||||
}
|
||||
all = all->tl;
|
||||
}
|
||||
}
|
||||
|
||||
void guaranteedtrue(fma *f,intset ac) {
|
||||
fmalist *fs;
|
||||
switch(f->t) {
|
||||
case FALSE:
|
||||
case TRUE:
|
||||
break;
|
||||
case conj:
|
||||
fs = f->juncts;
|
||||
while(fs != NULL) {
|
||||
guaranteedtrue(fs->hd,ac);
|
||||
fs = fs->tl;
|
||||
}
|
||||
break;
|
||||
case disj: break;
|
||||
case patom: ISinsert(fePLIT(f->a),ac); break;
|
||||
case natom: ISinsert(feNLIT(f->a),ac); break;
|
||||
}
|
||||
}
|
||||
|
||||
int nofcondeffs(eff *e) {
|
||||
int cnt;
|
||||
cnt = 0;
|
||||
while(e != NULL) {
|
||||
cnt = cnt + 1;
|
||||
e = e->tl;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
llist **prepros; /* */
|
||||
|
||||
void preprocess() {
|
||||
int i,j,effcnt;
|
||||
intset preconlits;
|
||||
eff *e;
|
||||
|
||||
prepros = (llist **)statmalloc(401,nOfActions * sizeof(llist *));
|
||||
preconlits = IScreate(1000);
|
||||
|
||||
for(i=0;i<nOfActions;i++) {
|
||||
|
||||
e = &(actions[i].effects);
|
||||
|
||||
effcnt = nofcondeffs(e);
|
||||
|
||||
prepros[i] = statmalloc(402,sizeof(llist) * effcnt);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Preprocessing for operator %i:",i); fflush(stdout);
|
||||
printaction(i); fflush(stdout);
|
||||
#endif
|
||||
|
||||
ISmakeempty(preconlits);
|
||||
|
||||
guaranteedtrue(actions[i].precon,preconlits);
|
||||
|
||||
j = 0;
|
||||
|
||||
while(e != NULL) { /* Go through the conditional effects */
|
||||
|
||||
prepros[i][j].before = IScreateSize(10);
|
||||
|
||||
guaranteedtrue(e->condition,prepros[i][j].before);
|
||||
ISaddelements(preconlits,prepros[i][j].before);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("BEFORE"); fflush(stdout);
|
||||
printlitlist(prepros[i][j].before); fflush(stdout);
|
||||
printf("\n"); fflush(stdout);
|
||||
#endif
|
||||
|
||||
prepros[i][j].after = IScreateSize(20);
|
||||
|
||||
addeffectlitsL(e->effectlits,e,&(actions[i].effects),prepros[i][j].after);
|
||||
#ifdef DEBUG
|
||||
printf("AFTER"); fflush(stdout);
|
||||
printlitlist(prepros[i][j].after); fflush(stdout);
|
||||
printf("\n\n"); fflush(stdout);
|
||||
#endif
|
||||
|
||||
e = e->tl;
|
||||
j = j + 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int **alleffectlits;
|
||||
|
||||
int nofeffectlits(eff *e) {
|
||||
int cnt = 0;
|
||||
int *ptr;
|
||||
|
||||
while(e != NULL) {
|
||||
ptr = e->effectlits;
|
||||
while(*ptr != -1) {
|
||||
cnt = cnt + 1;
|
||||
ptr = ptr + 1;
|
||||
}
|
||||
e = e-> tl;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
void preprocess2() {
|
||||
int i,sz;
|
||||
eff *e;
|
||||
int *ptr,*fill;
|
||||
|
||||
alleffectlits = (int **)statmalloc(499,nOfActions * sizeof(int *));
|
||||
for(i=0;i<nOfActions;i++) {
|
||||
sz = 1 + nofeffectlits(&(actions[i].effects));
|
||||
alleffectlits[i] = (int *)statmalloc(498,sz * sizeof(int));
|
||||
fill = alleffectlits[i];
|
||||
e = &(actions[i].effects);
|
||||
while(e != NULL) {
|
||||
ptr = e->effectlits;
|
||||
while(*ptr != -1) {
|
||||
*fill = *ptr;
|
||||
fill = fill + 1;
|
||||
ptr = ptr + 1;
|
||||
}
|
||||
e = e->tl;
|
||||
}
|
||||
*fill = -1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CFMA
|
||||
inline int ctruep(cfma f) {
|
||||
|
||||
switch(((int)f)&7) {
|
||||
|
||||
case cNATOMtag: return (onelits[((int)f) >> 3] != 1);
|
||||
case cPATOMtag: return (onelits[((int)f) >> 3] != 0);
|
||||
case cTRUEtag: return 1;
|
||||
case cFALSEtag: return 0;
|
||||
|
||||
default:
|
||||
|
||||
if(((int)(*f))&1) { /* Conjunction */
|
||||
|
||||
int i,cnt;
|
||||
cnt = ((int)(f[0])) >> 1;
|
||||
|
||||
for(i=0;i<cnt;i++) {
|
||||
if(!ctruep(f[i+1])) return 0;
|
||||
}
|
||||
return 1;
|
||||
|
||||
} else { /* Disjunction */
|
||||
|
||||
int i,cnt;
|
||||
cnt = ((int)(f[0])) >> 1;
|
||||
|
||||
for(i=0;i<cnt;i++) {
|
||||
if(ctruep(f[i+1])) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline int truep(fma *f) {
|
||||
fmalist *fs;
|
||||
switch(f->t) {
|
||||
case natom: return (onelits[f->a] != 1);
|
||||
case patom: return (onelits[f->a] != 0);
|
||||
case disj:
|
||||
fs = f->juncts;
|
||||
while(fs != NULL) {
|
||||
if(truep(fs->hd)) return 1;
|
||||
fs = fs->tl;
|
||||
}
|
||||
return 0;
|
||||
case conj:
|
||||
fs = f->juncts;
|
||||
while(fs != NULL) {
|
||||
if(!truep(fs->hd)) return 0;
|
||||
fs = fs->tl;
|
||||
}
|
||||
return 1;
|
||||
case TRUE: return 1;
|
||||
case FALSE: return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//int notmadefalse(int l,eff *e) {
|
||||
// int *ls;
|
||||
// while(e != NULL) {
|
||||
// ls = e->effectlits;
|
||||
// while(*ls != -1) {
|
||||
// if(l == feNEG(*ls)) return 0;
|
||||
// ls = ls + 1;
|
||||
// }
|
||||
// e = e->tl;
|
||||
// }
|
||||
// return 1;
|
||||
//}
|
||||
|
||||
int madefalse(int l,int i) {
|
||||
int *ptr;
|
||||
ptr = alleffectlits[i];
|
||||
while(*ptr != -1) {
|
||||
if(*ptr == feNEG(l)) return 1;
|
||||
ptr = ptr + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void removefalsified(eff *e,intset s) {
|
||||
int *ptr;
|
||||
while(e != NULL) {
|
||||
ptr = e->effectlits;
|
||||
while(*ptr != -1) { ISremove(feNEG(*ptr),s); ptr = ptr + 1; }
|
||||
e = e->tl;
|
||||
}
|
||||
}
|
||||
|
||||
int localISmember0(int i,intset s) {
|
||||
int j;
|
||||
for(j=0;j<s->nOfEls;j++) {
|
||||
if(s->elements[j] == i) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int localISmember1(int i,intset s) {
|
||||
int j;
|
||||
for(j=0;j<s->nOfEls;j++) {
|
||||
if(s->elements[j] == i) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int localISmember2(int i,intset s) {
|
||||
int j;
|
||||
|
||||
for(j=0;j<s->nOfEls;j++) {
|
||||
if(s->elements[j] == i) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int localISmember3(int i,intset s) {
|
||||
int j;
|
||||
for(j=0;j<s->nOfEls;j++) {
|
||||
if(s->elements[j] == i) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wastruebefore(int l,intset before) {
|
||||
int i;
|
||||
// if(localISmember(l,before)) return 1;
|
||||
/* Go through the relevant invariants. */
|
||||
for(i=0;i<before->nOfEls;i++) {
|
||||
if(before->elements[i] == l) return 1;
|
||||
if(localISmember0(l,twolits[feNEG(before->elements[i])])) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void computeinvariants() {
|
||||
int i,iteration,change,j,k;
|
||||
eff *e;
|
||||
int *il;
|
||||
llist *prep;
|
||||
intset trueones,ext;
|
||||
int trueonesinitialized;
|
||||
|
||||
preprocess();
|
||||
preprocess2();
|
||||
|
||||
ext = IScreateSize(10000);
|
||||
|
||||
trueones = IScreateSize(10000);
|
||||
|
||||
onelits = (int *)statmalloc(403,sizeof(int) * nOfAtoms);
|
||||
twolits = (intset *)statmalloc(404,sizeof(intset) * nOfAtoms * 2);
|
||||
|
||||
for(i=0;i<nOfAtoms;i++) {
|
||||
onelits[i] = initialstate[i];
|
||||
twolits[fePLIT(i)] = IScreate();
|
||||
twolits[feNLIT(i)] = IScreate();
|
||||
}
|
||||
|
||||
if(flagNoInvariants) {
|
||||
for(i=0;i<nOfAtoms;i++) {
|
||||
onelits[i] = -1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Invariants:");
|
||||
|
||||
iteration = 0;
|
||||
change = 1;
|
||||
|
||||
while(change) {
|
||||
|
||||
printf(" %i",iteration); fflush(stdout);
|
||||
change = 0;
|
||||
|
||||
for(i=0;i<nOfActions;i++) {
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("\nConsidering action %i:",i); fflush(stdout);
|
||||
printaction(i);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
/* Both the precondition and the cond. eff. antecedents are tested without looking at the mutexes: would not usually make a difference! */
|
||||
|
||||
#ifdef CFMA
|
||||
if(!ctruep(actions[i].cprecon)) continue; /* Not applicable (yet) */
|
||||
#else
|
||||
if(!truep(actions[i].precon)) continue; /* Not applicable (yet) */
|
||||
#endif
|
||||
|
||||
/* Go through all first-time falsified literals:
|
||||
weaken to all possible 2-literal clauses
|
||||
|
||||
Go through all 2-literal clauses with one disjunct falsified:
|
||||
must the other disjunct be true?
|
||||
*/
|
||||
|
||||
e = &(actions[i].effects);
|
||||
|
||||
/* prep is a list of known necessary preconditions and effects. */
|
||||
prep = prepros[i];
|
||||
|
||||
while(e != NULL) {
|
||||
|
||||
trueonesinitialized = 0;
|
||||
|
||||
#ifdef CFMA
|
||||
if(ctruep(e->ccondition)) {
|
||||
#else
|
||||
if(truep(e->condition)) {
|
||||
#endif
|
||||
|
||||
/* In the following:
|
||||
We have newly true literals in prep->after and
|
||||
all true literals in trueones.
|
||||
|
||||
For every l in prep->after and m in trueones, -l V m
|
||||
is an invariant.
|
||||
These are all invariants involving -l.
|
||||
|
||||
We want to store all of these such that both -l and m
|
||||
can have both value true and false.
|
||||
*/
|
||||
|
||||
/* Go through effect literals */
|
||||
|
||||
il = e->effectlits;
|
||||
|
||||
while(*il != -1) {
|
||||
int l;
|
||||
l = *il;
|
||||
il = il + 1;
|
||||
|
||||
/* See whether making literal l true falsifies something. */
|
||||
|
||||
if(onelits[feVAR(l)] == (l&1)) { /* Falsified a 1-literal */
|
||||
|
||||
if(trueonesinitialized == 0) {
|
||||
|
||||
trueonesinitialized = 1;
|
||||
ISmakeempty(trueones);
|
||||
|
||||
/* literals true because they are in the precondition */
|
||||
ISaddelements(prep->before,trueones);
|
||||
|
||||
/* literals true because a 2-literal clause is satisfied */
|
||||
iITstart(prep->before);
|
||||
while(iITnext(&j)) ISaddelements(twolits[feNEG(j)],trueones);
|
||||
|
||||
/* Remove literals that are falsified by this conditional effect
|
||||
or possibly by other conditional effects. */
|
||||
removefalsified(&(actions[i].effects),trueones);
|
||||
|
||||
/* Add literals that are made true. */
|
||||
ISaddelements(prep->after,trueones);
|
||||
}
|
||||
|
||||
change = 1;
|
||||
|
||||
onelits[feVAR(l)] = -1;
|
||||
|
||||
/* Add 2-literals -a | l */
|
||||
|
||||
iITstart(trueones);
|
||||
while(iITnext(&k)) {
|
||||
if(l != k && (onelits[feVAR(k)] == -1 || (localISmember1(k,prep->after) && onelits[feVAR(k)] == (k&1)))) {
|
||||
ISinsertNODUP(k,twolits[feNEG(l)]);
|
||||
ISinsertNODUP(feNEG(l),twolits[k]);
|
||||
}
|
||||
}
|
||||
} else if(onelits[feVAR(l)] == -1) { /* Check preservation of 2-literal clauses */
|
||||
|
||||
/* Remove candidate 2-literal invariants which were falsified. */
|
||||
|
||||
IScopyto(twolits[feNEG(l)],ext);
|
||||
|
||||
iITstart(ext);
|
||||
while(iITnext(&k)) {
|
||||
if(!(localISmember2(k,prep->after)
|
||||
|| (
|
||||
wastruebefore(k,prep->before)
|
||||
&&
|
||||
!madefalse(k,i)
|
||||
))) {
|
||||
change = 1;
|
||||
ISremove(k,twolits[feNEG(l)]);
|
||||
ISremove(feNEG(l),twolits[k]);
|
||||
}
|
||||
}
|
||||
|
||||
/* If enabled a new state variable value (= invalidated
|
||||
a candidate one-literal invariant), add new candidate
|
||||
two-literal invariants that still remain true. */
|
||||
|
||||
iITstart(prep->after);
|
||||
while(iITnext(&k)) {
|
||||
if(l != k && onelits[feVAR(k)] == -1 && localISmember3(k,twolits[feNEG(l)])) {
|
||||
ISinsert(feNEG(l),twolits[k]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
e = e->tl;
|
||||
prep++;
|
||||
}
|
||||
|
||||
// showInvariantsBrief();
|
||||
}
|
||||
|
||||
iteration += 1;
|
||||
}
|
||||
|
||||
for(i=0;i<nOfActions;i++) {
|
||||
// ISfree(prepros[i].before);
|
||||
// ISfree(prepros[i].after);
|
||||
free(prepros[i]);
|
||||
free(alleffectlits[i]);
|
||||
}
|
||||
|
||||
free(prepros);
|
||||
free(alleffectlits);
|
||||
|
||||
printf(" ");
|
||||
|
||||
if(flagShowInput) showInvariants();
|
||||
|
||||
}
|
7
invariants.h
Normal file
7
invariants.h
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
/* 2012 (C) Jussi Rintanen */
|
||||
|
||||
int *onelits;
|
||||
intset *twolits;
|
||||
|
||||
void computeinvariants();
|
335
learn2.c
Normal file
335
learn2.c
Normal file
@ -0,0 +1,335 @@
|
||||
|
||||
|
||||
/* This is the learning function that moves all non-decision literals
|
||||
directly to the clause array, without unnecessarily routing them through
|
||||
the stack first. */
|
||||
|
||||
|
||||
void learn(satinstance sati,int dlevel,int *CCdliteral,PTRINT *CCreason,int *maxnondecisionlevel) {
|
||||
|
||||
int ptr; /* Index to the last literal in the conflict clause */
|
||||
|
||||
int top; /* Index to the top of the stack */
|
||||
|
||||
int CCwatch1;
|
||||
int CCwatch2;
|
||||
|
||||
int *newClause;
|
||||
|
||||
int len,l,rl,i,j;
|
||||
PTRINT r;
|
||||
int *c;
|
||||
int *stck,*cc;
|
||||
|
||||
#ifdef MULTICORE
|
||||
stck = threads[sati->thread].stck;
|
||||
cc = threads[sati->thread].cc;
|
||||
#else
|
||||
stck = sati->stck;
|
||||
cc = sati->cc;
|
||||
#endif
|
||||
|
||||
#ifdef LBD
|
||||
int lbd;
|
||||
#endif
|
||||
|
||||
/* This counter is used for eliminating multiple occurrences of
|
||||
a literal from the derivation of the conflict clause.
|
||||
If the literal is associated with the current round, it has
|
||||
been seen already and will be ignored. */
|
||||
|
||||
nextround(sati);
|
||||
|
||||
ptr = -1; /* The clause we will learn is still empty. */
|
||||
top = -1; /* All literals in the clause are in the stack. */
|
||||
|
||||
*maxnondecisionlevel = -1; /* Highest non-decision level. */
|
||||
|
||||
if(sati->conflicttype2lit) { /* A 2-literal clause was falsified. */
|
||||
stck[0] = sati->conflictl1; /* Push both literals into the stack. */
|
||||
stck[1] = sati->conflictl2;
|
||||
|
||||
top = 1;
|
||||
|
||||
#ifdef MULTICORE
|
||||
threads[sati->thread].wasseen[sati->conflictl1] = threads[sati->thread].cround;
|
||||
threads[sati->thread].wasseen[sati->conflictl2] = threads[sati->thread].cround;
|
||||
#else
|
||||
wasseen[sati->conflictl1] = cround;
|
||||
wasseen[sati->conflictl2] = cround;
|
||||
#endif
|
||||
|
||||
#ifdef HARDDEBUG
|
||||
printf("Violated binary clause ");
|
||||
printTlit(sati,sati->conflictl1);
|
||||
printf(" ");
|
||||
printTlit(sati,sati->conflictl2);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
#ifdef ASSERTS
|
||||
assert(isliteral(sati,sati->conflictl1));
|
||||
assert(isliteral(sati,sati->conflictl2));
|
||||
#endif
|
||||
|
||||
} else { /* A clause of >= 3 literals was falsified. */
|
||||
|
||||
len = sati->conflictclause[PREFIX_CLAUSELEN];
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Violated clause %i (len %i):\n",(int)(sati->conflictclause),len);
|
||||
for(i=0;i<len;i++) { printTlit(sati,sati->conflictclause[i]); }
|
||||
// for(i=0;i<len;i++) { printf(" %i",sati->conflictclause[i]); }
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
#ifdef ASSERTS
|
||||
for(i=0;i<len;i++) assert(isliteral(sati,NEG(sati->conflictclause[i])));
|
||||
#endif
|
||||
|
||||
/* Push all literals in the clause into the stack or in the cc array. */
|
||||
for(i=0;i<len;i++) {
|
||||
#ifdef MULTICORE
|
||||
threads[sati->thread].wasseen[NEG(sati->conflictclause[i])] =
|
||||
threads[sati->thread].cround;
|
||||
#else
|
||||
wasseen[NEG(sati->conflictclause[i])] = cround;
|
||||
#endif
|
||||
if(LITDLEVEL(sati->conflictclause[i]) == dlevel) {
|
||||
stck[++top] = NEG(sati->conflictclause[i]);
|
||||
} else {
|
||||
int l = sati->conflictclause[i];
|
||||
if(LITREASON(l) != REASON_INPUT) {
|
||||
*maxnondecisionlevel = max(LITDLEVEL(l),*maxnondecisionlevel);
|
||||
cc[++ptr] = l;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// printf("FALSIFIED A %i-LITERAL CLAUSE.\n",len);
|
||||
|
||||
// for(i=0;i<=top;i++) printf("{%i}",sati->variabledlevel[VAR(stck[i])]);
|
||||
// for(i=0;i<=top;i++) printTlit(sati,stck[i]);
|
||||
// printf("\n");
|
||||
|
||||
CCwatch1 = -1;
|
||||
CCwatch2 = -1;
|
||||
|
||||
#ifdef ASSERTS
|
||||
assert(ptr<MAXCCLENGTH);
|
||||
assert(top<MAXCCLENGTH);
|
||||
assert(ptr>=-1);
|
||||
assert(top>=0); /* Necessarily at least one literal at the decision level. */
|
||||
#endif
|
||||
|
||||
while(top >= 0) {
|
||||
|
||||
l = stck[top--]; /* Pop literal from the stack. */
|
||||
|
||||
#ifdef ASSERTS
|
||||
assert(ptr<MAXCCLENGTH);
|
||||
assert(top<MAXCCLENGTH);
|
||||
assert(isliteral(sati,l));
|
||||
assert(!litunsetp(sati,l));
|
||||
assert(top>=-1);
|
||||
#endif
|
||||
|
||||
r = LITREASON(l);
|
||||
|
||||
/* Infer (learn) a new clause from the falsified clause, one literal
|
||||
at a time. */
|
||||
|
||||
if(r == REASON_DECISION) { /* It is the decision literal. */
|
||||
cc[++ptr] = NEG(l);
|
||||
CCwatch1 = NEG(l);
|
||||
*CCdliteral = NEG(l);
|
||||
} else if(r&1) { /* Reason is a literal (2 lit clause) */
|
||||
#ifdef WEIGHTS
|
||||
increase_score(sati,l); /* Increase score */
|
||||
#endif
|
||||
|
||||
if(!seenp(sati,r >> 1)) {
|
||||
stck[++top] = (r >> 1);
|
||||
#ifdef ASSERTS
|
||||
assert(isliteral(sati,r >> 1));
|
||||
#endif
|
||||
}
|
||||
} else { /* Reason is a clause */
|
||||
#ifdef WEIGHTS
|
||||
increase_score(sati,l); /* Increase score */
|
||||
#endif
|
||||
|
||||
c = (int *)r;
|
||||
while(*c != -1) { /* Literals except l into the stack or into the CC. */
|
||||
if(VAR(*c) != VAR(l) && !seenp(sati,NEG(*c))) {
|
||||
if(LITDLEVEL(*c) == dlevel) {
|
||||
stck[++top] = NEG(*c);
|
||||
} else {
|
||||
*maxnondecisionlevel = max(LITDLEVEL(*c),*maxnondecisionlevel);
|
||||
cc[++ptr] = *c;
|
||||
}
|
||||
}
|
||||
c += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ASSERTS
|
||||
assert(ptr<MAXCCLENGTH);
|
||||
assert(top<MAXCCLENGTH);
|
||||
assert(top>=-1);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Learned clause %i (%i lits):",clausecount,ptr+1);
|
||||
for(i=0;i<=ptr;i++) { printf(" %i:",VAR(cc[i])); printTlit(sati,cc[i]); }
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
#ifdef ASSERTS
|
||||
/* See that the learned clause is false in the current valuation. */
|
||||
for(i=0;i<=ptr;i++) {
|
||||
assert(!littruep(sati,cc[i]));
|
||||
assert(!litunsetp(sati,cc[i]));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Minimize the size of the learned clause:
|
||||
1. Mark all literals in the clause.
|
||||
2. Remove literals whose parent is marked.
|
||||
*/
|
||||
|
||||
#define noMINIMIZE
|
||||
|
||||
#ifdef MINIMIZE
|
||||
{
|
||||
PTRINT rr;
|
||||
cround += 1;
|
||||
for(i=0;i<=ptr;i++) wasseen[NEG(cc[i])] = cround;
|
||||
i = 0;
|
||||
while(i<=ptr) {
|
||||
rr = LITREASON(cc[i]);
|
||||
if(rr != REASON_DECISION && (((int)rr)&1) && (wasseen[((int)rr) >> 1] == cround)) { /* Remove. */
|
||||
// printf("*");
|
||||
cc[i] = cc[ptr--];
|
||||
} else {
|
||||
if(LITDLEVEL(cc[i]) == *maxnondecisionlevel) CCwatch2 = cc[i];
|
||||
i = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
for(i=0;i<=ptr;i++) {
|
||||
if(LITDLEVEL(cc[i]) == *maxnondecisionlevel) {
|
||||
CCwatch2 = cc[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LBD
|
||||
/* Calculate the Literal Block Distance LBD of Laurent & Simon IJCAI'09. */
|
||||
|
||||
lbd = 0;
|
||||
sati->LBDcounter += 1;
|
||||
for(i=0;i<=ptr;i++) {
|
||||
if(sati->LBDflag[LITDLEVEL(cc[i])] != sati->LBDcounter) {
|
||||
lbd += 1;
|
||||
sati->LBDflag[LITDLEVEL(cc[i])] = sati->LBDcounter;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//printf("LEARNED A %i-LITERAL CLAUSE.\n",ptr+1);
|
||||
//if(ptr+1 > 20000) printf("QZ(%i,%i)",ptr+1,dlevel);
|
||||
|
||||
// printf("ADDING NEW CLAUSE, ptr == %i\n",ptr);
|
||||
|
||||
/* Add the new clause to the clause set. */
|
||||
|
||||
if(ptr+1 > stats_longest_learned) stats_longest_learned = ptr+1;
|
||||
|
||||
if(ptr >= 2) { /* Clause with at least 3 literals */
|
||||
|
||||
#ifdef ASSERTS
|
||||
assert(isliteral(sati,CCwatch1));
|
||||
assert(isliteral(sati,CCwatch2));
|
||||
assert(CCwatch1 != CCwatch2);
|
||||
#endif
|
||||
|
||||
newClause = allocclause(sati->id,ptr+1);
|
||||
|
||||
// updateactivity(newClause,sati->conflicts);
|
||||
newClause[PREFIX_ACTIVITY] = sati->conflicts;
|
||||
|
||||
#ifdef LBD
|
||||
// printf("/%i/",lbd);
|
||||
setLBD(newClause,lbd);
|
||||
#endif
|
||||
|
||||
/* The watched literals are the ones with the highest levels,
|
||||
that is, the one at the decision level and one on the
|
||||
next highest level. */
|
||||
|
||||
newClause[0] = CCwatch1;
|
||||
newClause[1] = CCwatch2;
|
||||
|
||||
#ifdef WEIGHTS
|
||||
increase_score(sati,newClause[0]);
|
||||
increase_score(sati,newClause[1]);
|
||||
#endif
|
||||
|
||||
// Sort the learned clause. Impact on total runtime???????
|
||||
qsort(cc,ptr+1,sizeof(int),litCmp);
|
||||
|
||||
j = 2;
|
||||
for(i=0;i<=ptr;i++) {
|
||||
#ifdef ASSERTS
|
||||
assert(isliteral(sati,cc[i]));
|
||||
// assert(cc[i] != cc[i+1]);
|
||||
#endif
|
||||
if(cc[i] != CCwatch1 && cc[i] != CCwatch2) {
|
||||
newClause[j++] = cc[i];
|
||||
#ifdef WEIGHTS
|
||||
increase_score(sati,newClause[j-1]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ASSERTS
|
||||
assert(j == ptr+1);
|
||||
assert(newClause[ptr+1] == -1);
|
||||
#endif
|
||||
|
||||
*CCreason = (PTRINT)newClause;
|
||||
|
||||
setwatch(sati,CCwatch1,(int *)(*CCreason),0);
|
||||
setwatch(sati,CCwatch2,(int *)(*CCreason),1);
|
||||
|
||||
} else if(ptr == 1) { /* Clause with 2 literals */
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("LEARNED A 2-LITERAL CLAUSE (horizon %i)\n",sati->nOfTPoints);
|
||||
#endif
|
||||
|
||||
add2clause(sati,cc[0],cc[1],InitC);
|
||||
|
||||
if(cc[0] == *CCdliteral) rl = cc[1];
|
||||
else rl = cc[0];
|
||||
*CCreason = ((NEG(rl))<< 1)|1;
|
||||
|
||||
} else { /* Unit clause */
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("LEARNED A 1-LITERAL CLAUSE! (horizon %i)\n",sati->nOfTPoints);
|
||||
#endif
|
||||
#ifdef UCC
|
||||
addUCC(sati,cc[0]);
|
||||
#endif
|
||||
*CCreason = REASON_INPUT;
|
||||
*maxnondecisionlevel = 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
161
lexer.lex
Normal file
161
lexer.lex
Normal file
@ -0,0 +1,161 @@
|
||||
|
||||
/* 2012 (C) Jussi Rintanen */
|
||||
|
||||
/* Definitions */
|
||||
|
||||
%{
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "asyntax.h"
|
||||
#include "parser.tab.h"
|
||||
#include "main.h"
|
||||
|
||||
#include "tables.h"
|
||||
|
||||
int lexeropen(char *fn) {
|
||||
yyin = fopen(fn,"r");
|
||||
if(yyin == NULL) {
|
||||
fprintf(stderr,"ERROR: opening file %s\n",fn);
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lexeropenstdin() {
|
||||
yyin = stdin;
|
||||
nOfInputFiles = 0;
|
||||
currentInputFile=-1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int yywrap() {
|
||||
linenumber = 1;
|
||||
if(currentInputFile == nOfInputFiles-1) return 1;
|
||||
fclose(yyin);
|
||||
currentInputFile += 1;
|
||||
yyin = fopen(inputfiles[currentInputFile],"r");
|
||||
if(yyin == NULL) {
|
||||
fprintf(stderr,"ERROR: opening input file #%i: %s",currentInputFile,inputfiles[currentInputFile]);
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lowercase(char *tmp) {
|
||||
while(*tmp != 0) {
|
||||
if(*tmp >= 'A' && *tmp <= 'Z') *tmp += ('a'-'A');
|
||||
tmp += 1;
|
||||
}
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
ALPHA [a-zA-Z]
|
||||
ALPNUM [0-9a-zA-Z\-_,/]
|
||||
NUM [0-9]
|
||||
|
||||
%%
|
||||
|
||||
":"{ALPHA}{ALPNUM}* {
|
||||
lowercase(yytext);
|
||||
#ifdef DEBUG
|
||||
printf(":ID %s\n",yytext);
|
||||
#endif
|
||||
if(strcmp(yytext,":action") == 0) return rwACTION;
|
||||
if(strcmp(yytext,":parameters") == 0) return rwPARAMS;
|
||||
if(strcmp(yytext,":effect") == 0) return rwEFFECT;
|
||||
if(strcmp(yytext,":precondition") == 0) return rwPRECOND;
|
||||
if(strcmp(yytext,":predicates") == 0) return rwPREDICATES;
|
||||
if(strcmp(yytext,":requirements") == 0) return rwREQUIREMENTS;
|
||||
if(strcmp(yytext,":functions") == 0) return rwFUNCTIONS;
|
||||
if(strcmp(yytext,":types") == 0) return rwTYPES;
|
||||
if(strcmp(yytext,":constants") == 0) return rwCONSTANTS;
|
||||
if(strcmp(yytext,":objects") == 0) return rwOBJECTS;
|
||||
if(strcmp(yytext,":init") == 0) return rwINIT;
|
||||
if(strcmp(yytext,":goal") == 0) return rwGOAL;
|
||||
if(strcmp(yytext,":domain") == 0) return rwDOMAIN;
|
||||
if(strcmp(yytext,":metric") == 0) return rwMETRIC;
|
||||
|
||||
yylval.i = symbolindex(yytext);
|
||||
return ID;
|
||||
}
|
||||
|
||||
{ALPHA}{ALPNUM}* {
|
||||
lowercase(yytext);
|
||||
#ifdef DEBUG
|
||||
printf("ID %s\n",yytext);
|
||||
#endif
|
||||
|
||||
if(strcmp(yytext,"define") == 0) return rwDEFINE;
|
||||
if(strcmp(yytext,"and") == 0) return rwAND;
|
||||
if(strcmp(yytext,"or") == 0) return rwOR;
|
||||
if(strcmp(yytext,"imply") == 0) return rwIMPLY;
|
||||
if(strcmp(yytext,"when") == 0) return rwWHEN;
|
||||
if(strcmp(yytext,"not") == 0) return rwNOT;
|
||||
if(strcmp(yytext,"exists") == 0) return rwEXISTS;
|
||||
if(strcmp(yytext,"forall") == 0) return rwFORALL;
|
||||
if(strcmp(yytext,"problem") == 0) return rwPROBLEM;
|
||||
if(strcmp(yytext,"domain") == 0) return rwDOMAIN;
|
||||
if(strcmp(yytext,"either") == 0) return rwEITHER;
|
||||
if(strcmp(yytext,"increase") == 0) return rwINCREASE;
|
||||
if(strcmp(yytext,"minimize") == 0) return rwMINIMIZE;
|
||||
|
||||
yylval.i = symbolindex(yytext);
|
||||
return ID;
|
||||
}
|
||||
|
||||
"?"{ALPHA}{ALPNUM}* {
|
||||
lowercase(yytext);
|
||||
#ifdef DEBUG
|
||||
printf("VAR %s\n",yytext);
|
||||
#endif
|
||||
yylval.i = symbolindex(yytext);
|
||||
return VAR;
|
||||
}
|
||||
|
||||
{NUM}{NUM}* {
|
||||
sscanf(yytext,"%d",&yylval.i);
|
||||
return INT;
|
||||
}
|
||||
|
||||
"(" {
|
||||
#ifdef DEBUG
|
||||
printf("Left (\n");
|
||||
#endif
|
||||
return LPAREN;
|
||||
}
|
||||
|
||||
|
||||
")" {
|
||||
#ifdef DEBUG
|
||||
printf("Right )\n");
|
||||
#endif
|
||||
return RPAREN;
|
||||
}
|
||||
|
||||
"-" {
|
||||
#ifdef DEBUG
|
||||
printf("DASH\n");
|
||||
#endif
|
||||
return DASH;
|
||||
}
|
||||
|
||||
"=" {
|
||||
#ifdef DEBUG
|
||||
printf("EQUA\n");
|
||||
#endif
|
||||
return EQUA;
|
||||
}
|
||||
|
||||
[ \015\t]+ { }
|
||||
|
||||
\n { linenumber += 1; }
|
||||
|
||||
";".*\n { linenumber += 1; }
|
||||
|
||||
. printf("Unrecognized character %i '%s'\n",yytext[0],yytext);
|
||||
|
||||
%%
|
||||
|
||||
/* User subroutines */
|
755
main.c
Normal file
755
main.c
Normal file
@ -0,0 +1,755 @@
|
||||
|
||||
/* 2012 (C) Jussi Rintanen jrintanen.jr@gmail.com */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "asyntax.h"
|
||||
#include "intsets.h"
|
||||
#include "ordintsets.h"
|
||||
|
||||
#include "interface.h"
|
||||
#include "dimacsinput.h"
|
||||
#include "clausedb.h"
|
||||
|
||||
#include "operators.h"
|
||||
#include "tables.h"
|
||||
//#include "staticpredicates.h"
|
||||
#include "cleanup.h"
|
||||
#include "invariants.h"
|
||||
#include "scc.h"
|
||||
#include "translate2sat.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/times.h>
|
||||
#include <sys/time.h>
|
||||
#include <limits.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef MULTICORE
|
||||
#include <omp.h>
|
||||
#endif
|
||||
|
||||
char state_for_random[256];
|
||||
char dump_for_random[256];
|
||||
|
||||
char stri[1000];
|
||||
|
||||
long time10ms() { /* The time spent in user mode in 100ms */
|
||||
struct tms TMS;
|
||||
times(&TMS);
|
||||
return TMS.tms_utime / (sysconf(_SC_CLK_TCK) / 100);
|
||||
}
|
||||
|
||||
int abstimesec() {
|
||||
struct timeval aux;
|
||||
gettimeofday(&aux,NULL);
|
||||
return aux.tv_sec;
|
||||
}
|
||||
|
||||
int abstimeusec() {
|
||||
struct timeval aux;
|
||||
gettimeofday(&aux,NULL);
|
||||
return aux.tv_usec;
|
||||
}
|
||||
|
||||
intset test;
|
||||
|
||||
void givememorystatistics() {
|
||||
char buf[30];
|
||||
snprintf(buf, 30, "/proc/%u/statm", (unsigned)getpid());
|
||||
FILE* pf = fopen(buf, "r");
|
||||
|
||||
|
||||
if (pf) {
|
||||
unsigned size; // total program size
|
||||
unsigned resident;// resident set size
|
||||
unsigned share;// shared pages
|
||||
unsigned text;// text (code)
|
||||
unsigned lib;// library
|
||||
unsigned data;// data/stack
|
||||
int MB;
|
||||
|
||||
fscanf(pf, "%u %u %u %u %u %u", &size, &resident, &share, &text, &lib, &data);
|
||||
|
||||
MB = ((double)size)/256.0;
|
||||
|
||||
printf("total size %.3f %s\n",
|
||||
/*
|
||||
resident size: %u\n
|
||||
shared pages : %u\n
|
||||
text (code) : %u\n
|
||||
library : %u\n
|
||||
data/stack : %u\n",
|
||||
*/
|
||||
(MB < 700.0) ? MB : MB / 1024.0,
|
||||
(MB < 700.0) ? "MB" : "GB");
|
||||
}
|
||||
fclose(pf);
|
||||
}
|
||||
|
||||
/***************** MALLOC STATISTICS *****************/
|
||||
|
||||
#define noSHOWMALLOCSTATS
|
||||
|
||||
#ifdef SHOWMALLOCSTATS
|
||||
long statmallocs[1000];
|
||||
|
||||
void initstatmalloc() {
|
||||
int i;
|
||||
allocatedbyFE = 0.0;
|
||||
for(i=0;i<1000;i++) statmallocs[i] = 0;
|
||||
}
|
||||
|
||||
void showstatsmalloc() {
|
||||
int i;
|
||||
double sum;
|
||||
sum = 0.0;
|
||||
printf("Malloc statistics:\n");
|
||||
for(i=0;i<1000;i++) {
|
||||
if(statmallocs[i]) {
|
||||
printf("%i: %.2f\n",i,((float)statmallocs[i])/1024.0/1024.0);
|
||||
sum = sum + ((double)statmallocs[i])/1024.0/1024.0;
|
||||
}
|
||||
}
|
||||
printf("TOTAL = %.2f\n",sum);
|
||||
}
|
||||
#endif
|
||||
|
||||
void *statmalloc(int n,int s) {
|
||||
void *tmp;
|
||||
tmp = malloc(s);
|
||||
#ifdef SHOWMALLOCSTATS
|
||||
statmallocs[n] += s;
|
||||
assert(tmp);
|
||||
#else
|
||||
allocatedbyFE += s;
|
||||
#endif
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
/******************** TIME OUTS ********************/
|
||||
|
||||
void timeouthandler(int i) {
|
||||
printf("\nTimeout after %i seconds of real time.\n",flagRealTimeout);
|
||||
givememorystatistics();
|
||||
#ifdef SHOWMALLOCSTATS
|
||||
showstatsmalloc();
|
||||
#endif
|
||||
exit(0);
|
||||
}
|
||||
|
||||
float time2real(long dif) {
|
||||
return ((float)dif)/100.0;
|
||||
}
|
||||
|
||||
float timefromstart() {
|
||||
return time2real(time10ms() - TIMEstart);
|
||||
}
|
||||
|
||||
int numer(char c) {
|
||||
return (c >= '0' && c <= '9');
|
||||
}
|
||||
|
||||
void processheuristic(char *decls) {
|
||||
int position,n;
|
||||
|
||||
HEURordmode = 0;
|
||||
HEURordmin = 0;
|
||||
HEURordrnd = 0;
|
||||
|
||||
HEURtime = 0;
|
||||
HEURops = 0;
|
||||
HEURchoice = 0;
|
||||
|
||||
HEURactions = 1;
|
||||
HEURactionchoice = 0;
|
||||
HEURactiondepthlimit = 0;
|
||||
|
||||
position = 0;
|
||||
|
||||
if(!numer(*decls)) {
|
||||
printf("ERROR: Expected numeric option.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
do {
|
||||
|
||||
n = 0;
|
||||
|
||||
while(numer(*decls)) {
|
||||
n = n*10 + (*(decls++) - '0');
|
||||
}
|
||||
|
||||
if(*decls != 0 && *decls != ':') {
|
||||
printf("ERROR: Number separator is : and not %c.\n",*decls);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
switch(position) {
|
||||
case 0: HEURordmode = n; break;
|
||||
case 1: HEURordmin = n; break;
|
||||
case 2: HEURordrnd = n; break;
|
||||
case 3: HEURtime = n; break;
|
||||
case 4: HEURops = n; break;
|
||||
case 5: HEURchoice = n; break;
|
||||
case 6: HEURactions = n; break;
|
||||
case 7: HEURactionchoice = n; break;
|
||||
case 8: HEURactiondepthlimit = n; break;
|
||||
default: printf("ERROR: too many parameters.\n"); exit(1);
|
||||
}
|
||||
|
||||
position += 1;
|
||||
|
||||
} while(*(decls++) == ':');
|
||||
|
||||
}
|
||||
|
||||
int main(int argc,char **argv) {
|
||||
int i,j;
|
||||
|
||||
syntacticclass sclass;
|
||||
|
||||
nOfInputFiles = 0;
|
||||
|
||||
TIMEstartReal = time(NULL);
|
||||
TIMEstart = time10ms();
|
||||
#include "zPRINTDATE"
|
||||
|
||||
#ifdef __LP64__
|
||||
printf(" amd64");
|
||||
#else
|
||||
printf(" x86-32");
|
||||
#endif
|
||||
|
||||
#ifdef MULTICORE
|
||||
printf(" multi-core");
|
||||
#else
|
||||
printf(" 1-core");
|
||||
#endif
|
||||
|
||||
#ifdef VSIDS
|
||||
printf("\n");
|
||||
#else
|
||||
printf(" (no VSIDS)\n");
|
||||
#endif
|
||||
|
||||
#ifdef MULTICORE
|
||||
nOfThreads = omp_get_num_procs();
|
||||
printf("%i CPUS available\n",nOfThreads);
|
||||
#endif
|
||||
|
||||
stats_longest_learned = 0;
|
||||
|
||||
/* Process command line options. */
|
||||
|
||||
flagShortCutHorizon = 5;
|
||||
|
||||
flagShowInput = 0;
|
||||
flagPDDLadddel = 1;
|
||||
flagRestartInterval = 60;
|
||||
flagRestartScheme = 0;
|
||||
flagPreprocessing = 0;
|
||||
flagCEvariables = 1;
|
||||
flagRandomSeedTime = 0;
|
||||
flagNoInvariants = 0;
|
||||
flagEliminateConverses = 1;
|
||||
|
||||
currentInputFile = 0;
|
||||
outputfile = NULL;
|
||||
|
||||
#ifdef __LP64__
|
||||
flagMemoryLimit = 8.0*1024.0; /* By default, use max 8 GB of memory. */
|
||||
#else
|
||||
flagMemoryLimit = 3500.0; /* By default, use max 3.5 GB of memory. */
|
||||
#endif
|
||||
|
||||
flagOutputDIMACS = 0;
|
||||
flagIPCplans = 0;
|
||||
|
||||
#if (MPDOWNLOAD || CMPDOWNLOAD)
|
||||
PLANheuristic = 1;
|
||||
HEURordmode = 1;
|
||||
HEURordmin = 0;
|
||||
HEURordrnd = 0;
|
||||
HEURtime = 0;
|
||||
HEURops = 1; /* This was 0 for long. */
|
||||
HEURchoice = 0;
|
||||
HEURactions = 50; /* This was 40 for the AIJ article. */
|
||||
HEURactionchoice = 4;
|
||||
HEURactiondepthlimit = 1;
|
||||
#else
|
||||
PLANheuristic = 0; /* By default don't use planning heuristic, but VSIDS. */
|
||||
#endif
|
||||
|
||||
flagTimeout = 0;
|
||||
flagRealTimeout = 0;
|
||||
|
||||
lastTimePoint = 3000;
|
||||
outputTimeStep = 5;
|
||||
|
||||
firstTimePoint = 0;
|
||||
debugOutput = 0;
|
||||
|
||||
#ifdef CMPDOWNLOAD
|
||||
evalAlgorithm = 2;
|
||||
paramC = 1.414214; /* Default: Algorithm C */
|
||||
#else
|
||||
evalAlgorithm = 1;
|
||||
paramB = 0.9; /* Default: Algorithm B */
|
||||
#endif
|
||||
|
||||
paramM = 20;
|
||||
|
||||
planFrontend = 1;
|
||||
planSemantics = EStep;
|
||||
|
||||
filenamebase = NULL;
|
||||
|
||||
if(argc == 1) {
|
||||
printf("\n");
|
||||
printf("The command line parameters are the input file names and options:\n");
|
||||
printf("-A n Run algorithm A with parameter n (range 1 to 50)"); if(evalAlgorithm==0) printf(" default -A %i.\n",paramA); else printf("\n");
|
||||
printf("-B r Run algorithm B with parameter r (range 0.1 to 0.9999)"); if(evalAlgorithm==1) printf(" default -B %.2f.\n",paramB); else printf("\n");
|
||||
printf("-C r Run algorithm C with parameter r (range 1.2 to 2.0)"); if(evalAlgorithm==2) printf(" default -C %.2f.\n",paramC); else printf("\n");
|
||||
printf("-M n With algorithm B, use maximum n processes (default -M %i).\n",paramM);
|
||||
printf("-S n Step for horizon lengths 0,n,2n,3n,... (default -S %i, algorithms A and B only)\n",outputTimeStep);
|
||||
// printf("-H n Use SAT heuristic n.\n");
|
||||
// printf("-pH n Use planning heuristic n (0 = none).\n");
|
||||
printf("-F n Starting horizon length (default -F %i)\n",firstTimePoint);
|
||||
printf("-T n Ending horizon length (default -T %i)\n",lastTimePoint);
|
||||
printf("-P n Choose plan type n: (default -P 2)\n");
|
||||
printf(" 0 = sequential plans\n");
|
||||
printf(" 1 = A-step plans (Graphplan parallelism)\n");
|
||||
printf(" 2 = E-step plans (Rintanen et al. 2004, 2006)\n");
|
||||
// printf(" 3 = E-step plans (Ogata et al. 2004)\n");
|
||||
printf("-O Write formulas in a file in DIMACS format instead of solving.\n");
|
||||
printf("-X Don't use PDDL semantics for simultaneous v:=0 v:=1.\n");
|
||||
printf("-Q Output plans in the IPC format.\n");
|
||||
printf("-o [filename] Output plan to file.\n");
|
||||
printf("-b [filename] Name for the DIMACS CNF files.\n");
|
||||
printf("-t n Timeout n seconds of CPU time\n");
|
||||
printf("-r n Timeout n seconds of real time\n");
|
||||
printf("-m n Allocating max. n MB of memory (default -m %i)\n",(int)flagMemoryLimit);
|
||||
printf("-N Don't compute invariants.\n");
|
||||
printf("-c Don't eliminate converse literals.\n");
|
||||
printf("-W Use time as the random seed (instead of seed 0).\n");
|
||||
// printf("-Z n Select preprocessing.\n");
|
||||
printf("-i n Restart interval is n (default -i %i).\n",flagRestartInterval);
|
||||
printf("-R n Restart scheme n=0 constant n=1 Luby (default -R %i).\n",flagRestartScheme);
|
||||
#ifdef CP3
|
||||
printf("-E Use external preprocessor.\n");
|
||||
#endif
|
||||
// printf("-K n Add shortcuts for horizon n.\n");
|
||||
// printf("-I Show input and auxiliary data in detail.\n");
|
||||
// printf("-2 Use the closure of binary clauses to speed up propagation.\n");
|
||||
// printf("-d b Level of debug output (default = 0).\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
printf("Options:");
|
||||
|
||||
for(i=1;i<argc;i++) {
|
||||
if(argv[i][0] != '-') {
|
||||
printf(" file:%s",argv[i]);
|
||||
nOfInputFiles += 1;
|
||||
inputfiles[nOfInputFiles-1] = argv[i];
|
||||
} else {
|
||||
switch(argv[i][1]) {
|
||||
case 'A': /* evaluation algorithm A */
|
||||
if(!sscanf(argv[i+1],"%d",¶mA)) {
|
||||
printf("The -A parameter %s is not an integer.\n",argv[i+1]);
|
||||
exit(1);
|
||||
}
|
||||
evalAlgorithm = 0;
|
||||
i++;
|
||||
printf(" -A %i",paramA);
|
||||
break;
|
||||
case 'B': /* evaluation algorithm B */
|
||||
if(!sscanf(argv[i+1],"%f",¶mB)) {
|
||||
printf("The -B parameter %s is not an real.\n",argv[i+1]);
|
||||
exit(1);
|
||||
}
|
||||
evalAlgorithm = 1;
|
||||
i++;
|
||||
printf(" -B %.2f",paramB);
|
||||
break;
|
||||
case 'C': /* evaluation algorithm C */
|
||||
if(!sscanf(argv[i+1],"%f",¶mC)) {
|
||||
printf("The -B parameter %s is not an real.\n",argv[i+1]);
|
||||
exit(1);
|
||||
}
|
||||
evalAlgorithm = 2;
|
||||
i++;
|
||||
printf(" -C %.2f",paramC);
|
||||
break;
|
||||
case 'M':
|
||||
if(!sscanf(argv[i+1],"%d",¶mM)) {
|
||||
printf("The -M parameter %s is not an integer.\n",argv[i+1]);
|
||||
exit(1);
|
||||
}
|
||||
i++;
|
||||
printf(" -M %i",paramM);
|
||||
break;
|
||||
case 'H': /* Heuristic used by the solver */
|
||||
PLANheuristic = 1;
|
||||
processheuristic(argv[i+1]);
|
||||
printf(" -H %s",argv[i+1]);
|
||||
i++;
|
||||
break;
|
||||
case 'K': /* Shortcut horizon */
|
||||
if(!sscanf(argv[i+1],"%d",&flagShortCutHorizon)) {
|
||||
printf("The -K parameter %s is not an integer.\n",argv[i+1]);
|
||||
exit(1);
|
||||
}
|
||||
i++;
|
||||
printf(" -K %i",flagShortCutHorizon);
|
||||
break;
|
||||
case 'F': /* First time point to consider */
|
||||
if(!sscanf(argv[i+1],"%d",&firstTimePoint)) {
|
||||
printf("The -F parameter %s is not an integer.\n",argv[i+1]);
|
||||
exit(1);
|
||||
}
|
||||
i++;
|
||||
printf(" -F %i",firstTimePoint);
|
||||
break;
|
||||
case 'p': /* Outdated option */
|
||||
printf("option not available any more.\n");
|
||||
exit(1);
|
||||
break;
|
||||
case 'i': /* Restart interval */
|
||||
if(!sscanf(argv[i+1],"%d",&flagRestartInterval)) {
|
||||
printf("The -i parameter %s is not an integer.\n",argv[i+1]);
|
||||
exit(1);
|
||||
}
|
||||
i++;
|
||||
printf(" -i %i",flagRestartInterval);
|
||||
break;
|
||||
case 'R': /* Restart scheme */
|
||||
if(!sscanf(argv[i+1],"%d",&flagRestartScheme)) {
|
||||
printf("The -R parameter %s is not an integer.\n",argv[i+1]);
|
||||
exit(1);
|
||||
}
|
||||
i++;
|
||||
printf(" -R %i",flagRestartScheme);
|
||||
break;
|
||||
case 'T': /* Max time points to test */
|
||||
if(!sscanf(argv[i+1],"%d",&lastTimePoint)) {
|
||||
printf("The -T parameter %s is not an integer.\n",argv[i+1]);
|
||||
exit(1);
|
||||
}
|
||||
i++;
|
||||
printf(" -T %i",lastTimePoint);
|
||||
break;
|
||||
case 't': /* Time out */
|
||||
if(!sscanf(argv[i+1],"%d",&flagTimeout)) {
|
||||
printf("The -t parameter %s is not an integer.\n",argv[i+1]);
|
||||
exit(1);
|
||||
}
|
||||
i++;
|
||||
printf(" -t %i",flagTimeout);
|
||||
break;
|
||||
case 'r': /* Time out in Real time */
|
||||
if(!sscanf(argv[i+1],"%d",&flagRealTimeout)) {
|
||||
printf("The -r parameter %s is not an integer.\n",argv[i+1]);
|
||||
exit(1);
|
||||
}
|
||||
i++;
|
||||
printf(" -r %i",flagRealTimeout);
|
||||
break;
|
||||
case 'm': /* Memory limit */
|
||||
if(!sscanf(argv[i+1],"%d",&j)) {
|
||||
printf("The -m parameter %s is not an integer.\n",argv[i+1]);
|
||||
exit(1);
|
||||
}
|
||||
flagMemoryLimit = (float)j;
|
||||
i++;
|
||||
printf(" -m %i",(int)flagMemoryLimit);
|
||||
break;
|
||||
case 'd': /* Debug output level */
|
||||
if(!sscanf(argv[i+1],"%d",&debugOutput)) {
|
||||
printf("The -d parameter %s is not an integer.\n",argv[i+1]);
|
||||
exit(1);
|
||||
}
|
||||
i++;
|
||||
printf(" -d %i",debugOutput);
|
||||
break;
|
||||
case 'o': /* Output file name */
|
||||
outputfile=argv[i+1];
|
||||
i++;
|
||||
printf(" -o %s",outputfile);
|
||||
break;
|
||||
case 'b': /* Output file name for DIMACS CNF */
|
||||
filenamebase=argv[i+1];
|
||||
i++;
|
||||
printf(" -b %s",filenamebase);
|
||||
break;
|
||||
case 'S': /* Step */
|
||||
if(!sscanf(argv[i+1],"%d",&outputTimeStep)) {
|
||||
printf("The -S parameter %s is not an integer.\n",argv[i+1]);
|
||||
exit(1);
|
||||
}
|
||||
i++;
|
||||
printf(" -S %i",outputTimeStep);
|
||||
break;
|
||||
case 'X': /* Don't use PDDL semantics for v:=0 v:=1 assigning 0 first and then 1, without causing contradiction. */
|
||||
flagPDDLadddel = 0;
|
||||
printf(" -X");
|
||||
break;
|
||||
case 'W': /* Use time as random seed, instead of seed 0. */
|
||||
flagRandomSeedTime = 1;
|
||||
printf(" -W");
|
||||
break;
|
||||
case 'Z': /* Preprocessing options */
|
||||
if(!sscanf(argv[i+1],"%d",&flagPreprocessing)) {
|
||||
printf("The -Z parameter %s is not an integer.\n",argv[i+1]);
|
||||
exit(1);
|
||||
}
|
||||
i++;
|
||||
printf(" -Z %i",flagPreprocessing);
|
||||
break;
|
||||
case 'O': /* Output to DIMACS instead of running integrated SAT solver */
|
||||
flagOutputDIMACS = 1;
|
||||
break;
|
||||
case 'N': /* Don't compute invariants. */
|
||||
flagNoInvariants = 1;
|
||||
printf(" -N");
|
||||
break;
|
||||
case 'Q': /* Output to plans in IPC format */
|
||||
flagIPCplans = 1;
|
||||
break;
|
||||
case 'Y': /* Dummy 1-parameter option (for ignoring commandline args. */
|
||||
i++;
|
||||
break;
|
||||
case 'P': /* Parallel semantics */
|
||||
if(!sscanf(argv[i+1],"%d",&j)) {
|
||||
printf("The -P parameter %s is not an integer.\n",argv[i+1]);
|
||||
exit(1);
|
||||
}
|
||||
switch(j) {
|
||||
case 0: planSemantics = Sequ; break;
|
||||
case 1: planSemantics = AStep; break;
|
||||
case 2: planSemantics = EStep; break;
|
||||
case 3: planSemantics = EStepOgata; break;
|
||||
}
|
||||
i++;
|
||||
printf(" -P %i",j);
|
||||
break;
|
||||
case 'c':
|
||||
flagEliminateConverses = 0;
|
||||
printf(" -c");
|
||||
break;
|
||||
case 'I':
|
||||
flagShowInput = 1;
|
||||
printf(" -I");
|
||||
break;
|
||||
case 'D': /* Input file is a CNF in DIMACS format. */
|
||||
planFrontend = 0;
|
||||
printf(" -D");
|
||||
break;
|
||||
case 'E': /* Use (external) preprocessor. */
|
||||
flagExternalPreprocessor = 1;
|
||||
printf(" -E");
|
||||
break;
|
||||
default:
|
||||
printf("ignoring %s\n",argv[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
if(flagRandomSeedTime) srandom(abstimeusec());
|
||||
else srandom(0);
|
||||
|
||||
/***********************************************************************/
|
||||
/***********************************************************************/
|
||||
/************************** Show heuristics parameter settings *********/
|
||||
|
||||
#define noEXPLAINSETTINGS 1
|
||||
|
||||
#ifdef EXPLAINSETTINGS
|
||||
|
||||
switch(HEURops) {
|
||||
case 0: printf("Will consider the first (arbitrary) action only.\n"); break;
|
||||
case 1: printf("Will consider all actions available.\n"); break;
|
||||
case 2: printf("Will consider last computed only.\n"); break;
|
||||
}
|
||||
|
||||
switch(HEURtime) {
|
||||
case 0: printf("Earliest"); break;
|
||||
case 1: printf("Latest"); break;
|
||||
case 2: printf("Earliest..Latest"); break;
|
||||
}
|
||||
switch(HEURchoice) {
|
||||
case 0: printf(", chosen randomly.\n"); break;
|
||||
case 1: printf(", chosen randomly (biased).\n"); break;
|
||||
default: printf(", chosen according to weight.\n");
|
||||
}
|
||||
|
||||
printf("Compute %i suggested actions.\n",HEURactions);
|
||||
switch(HEURactionchoice) {
|
||||
case 0:
|
||||
printf("Choose between them randomly.\n"); break;
|
||||
case 1:
|
||||
printf("Choose suggested action of earliest time point.\n"); break;
|
||||
case 3:
|
||||
printf("Choose suggested action randomly.\n"); break;
|
||||
case 4:
|
||||
printf("Choose suggested action according to weight, with ties broken randomly.\n"); break;
|
||||
}
|
||||
|
||||
if(HEURactiondepthlimit) printf("For multiple suggested, only go deeper.\n");
|
||||
else printf("For multiple suggested, consider all.\n");
|
||||
#endif
|
||||
|
||||
if(flagRealTimeout) {
|
||||
alarm(flagRealTimeout);
|
||||
signal(SIGALRM,timeouthandler);
|
||||
}
|
||||
|
||||
#ifdef SHOWMALLOCSTATS
|
||||
initstatmalloc();
|
||||
#endif
|
||||
|
||||
/* ******************************************************************** */
|
||||
/* ******************************************************************** */
|
||||
/* ******************************************************************** */
|
||||
|
||||
#ifndef VSIDS
|
||||
if(PLANheuristic == 0) {
|
||||
fprintf(stderr,"ERROR: Trying to use VSIDS which was not compiled.\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if(planFrontend != 1) {
|
||||
solve(DIMACSinput());
|
||||
} else {
|
||||
readfile();
|
||||
printf("Domain: %s\nProblem: %s\n",domainname(),problemname());
|
||||
|
||||
// preprocessoperators();
|
||||
//
|
||||
// if(debugOutput >= 1) printf("Eliminating static...\n");
|
||||
//
|
||||
// eliminatestatic();
|
||||
// // simplifysillyconditionals();
|
||||
//
|
||||
// if(debugOutput >= 1) printf("Grounding...\n");
|
||||
//
|
||||
// groundoperators();
|
||||
|
||||
if(debugOutput >= 1) printf("Grounding...\n");
|
||||
|
||||
NEWgroundoperators();
|
||||
|
||||
printf("Parser: %i ground actions and %i state variables\n",nOfActions,nOfAtoms);
|
||||
|
||||
if(flagShowInput) {
|
||||
for(i=0;i<nOfActions;i++) printaction(i);
|
||||
}
|
||||
|
||||
if(flagShowInput) {
|
||||
printf("All atoms: ");
|
||||
for(i=0;i<nOfAtoms;i++) {
|
||||
printf(" %i:",i);
|
||||
printatomi(i); fflush(stdout);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if(debugOutput >= 1) printf("Cleaning up...\n");
|
||||
|
||||
cleanupoperators();
|
||||
|
||||
#ifdef SHOWMALLOCSTATS
|
||||
showstatsmalloc();
|
||||
#endif
|
||||
|
||||
TIMEinvariants = time10ms();
|
||||
|
||||
if(debugOutput >= 1) printf("Preparing to compute invariants...\n");
|
||||
|
||||
computeinvariants();
|
||||
if(!flagNoInvariants) printf(" %.2f secs\n", time2real(time10ms() - TIMEinvariants));
|
||||
|
||||
simplifyoperatorsstatic();
|
||||
|
||||
eliminatestaticvariables();
|
||||
|
||||
if(flagEliminateConverses) mergecontras();
|
||||
|
||||
printf("Simplified: %i ground actions and %i state variables\n",nOfActions,nOfAtoms);
|
||||
|
||||
sortactions();
|
||||
|
||||
if(flagShowInput) {
|
||||
for(i=0;i<nOfActions;i++) printaction(i);
|
||||
}
|
||||
|
||||
/* Is the problem instance STRIPS, conjunctive PDDL, or general PDDL? */
|
||||
sclass = goalclass();
|
||||
for(i=0;i<nOfActions;i++) {
|
||||
if(sclass == STRIPS && actionclass(i) == Conjunctive) sclass = Conjunctive;
|
||||
if(actionclass(i) == GeneralPDDL) {
|
||||
sclass = GeneralPDDL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(sclass) {
|
||||
case STRIPS: printf("Actions: STRIPS\n"); break;
|
||||
case Conjunctive: printf("Actions: conjunctive\n"); break;
|
||||
case GeneralPDDL: printf("Actions: general\n"); break;
|
||||
}
|
||||
|
||||
TIMEdisaprepro = time10ms();
|
||||
findoccurrences();
|
||||
if(debugOutput > 0) printf("time %.2f for preprocessing for disabling graph\n", time2real(time10ms() - TIMEdisaprepro));
|
||||
|
||||
if(planSemantics == EStep) {
|
||||
int maxsize;
|
||||
TIMEdisabling = time10ms();
|
||||
maxsize = scc(nOfActions);
|
||||
printf(" %.2f secs (max SCC size %i)\n",time2real(time10ms() - TIMEdisabling),maxsize);
|
||||
}
|
||||
|
||||
TIMEpreprocess = time10ms();
|
||||
|
||||
encoding();
|
||||
|
||||
printf("total time %.2f preprocess %.2f \n",
|
||||
time2real(time10ms() - TIMEstart),
|
||||
time2real(TIMEpreprocess - TIMEstart));
|
||||
|
||||
givememorystatistics();
|
||||
|
||||
printf("max. learned clause length %i\n",stats_longest_learned);
|
||||
|
||||
if(flagOutputDIMACS == 0) {
|
||||
printf("t val conflicts decisions\n");
|
||||
i = 0;
|
||||
do {
|
||||
printf("%i %i %i %i\n",seqs[i].sati->nOfTPoints-1,seqs[i].sati->value,seqs[i].sati->conflicts,seqs[i].sati->decisions);
|
||||
i += 1;
|
||||
} while(i*outputTimeStep+firstTimePoint <= lastTimePoint && seqs[i].sati && seqs[i-1].sati->value != 1);
|
||||
// } while(i*outputTimeStep+firstTimePoint < lastTimePoint);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef SHOWMALLOCSTATS
|
||||
showstatsmalloc();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
71
main.h
Normal file
71
main.h
Normal file
@ -0,0 +1,71 @@
|
||||
|
||||
/* 2010 (C) Jussi Rintanen */
|
||||
|
||||
int SATheuristic;
|
||||
int PLANheuristic;
|
||||
int planFrontend;
|
||||
int flagShowInput;
|
||||
int flagRestartInterval;
|
||||
int flagRestartScheme;
|
||||
int flagTimeout;
|
||||
int flagRealTimeout;
|
||||
int debugOutput;
|
||||
int flagPDDLadddel;
|
||||
int flagPreprocessing;
|
||||
int flagIPCplans;
|
||||
int flagCEvariables; /* Create a variable for each conditional effect. */
|
||||
int flagRandomSeedTime; /* Use the time as a random seed (instead of 0). */
|
||||
int flagNoInvariants;
|
||||
int flagEliminateConverses; /* Eliminate redundant converse literals. */
|
||||
int flagExternalPreprocessor;
|
||||
float flagMemoryLimit; /* Max. MB of memory allowed to allocate. */
|
||||
|
||||
long TIMEstartReal,TIMEstart,TIMEpreprocess,TIMEdisabling,TIMEdisaprepro,TIMEinvariants;
|
||||
|
||||
#ifdef MULTICORE
|
||||
int nOfThreads;
|
||||
#endif
|
||||
|
||||
float timefromstart();
|
||||
|
||||
double allocatedbyFE;
|
||||
|
||||
typedef enum { Sequ, EStep, EStepOgata, AStep } semantics;
|
||||
|
||||
semantics planSemantics;
|
||||
|
||||
int currentInputFile;
|
||||
int nOfInputFiles;
|
||||
char *inputfiles[10];
|
||||
char *outputfile;
|
||||
|
||||
int flagOutputDIMACS;
|
||||
|
||||
void *statmalloc(int,int);
|
||||
//#define statmalloc(a,b) malloc(b)
|
||||
|
||||
int firstTimePoint;
|
||||
int lastTimePoint;
|
||||
int outputTimeStep;
|
||||
|
||||
char *filenamebase;
|
||||
|
||||
int evalAlgorithm; /* 0 = A, 1 = B, 2 = C */
|
||||
int paramA;
|
||||
float paramB;
|
||||
float paramC;
|
||||
int paramM; /* Max. processes for algorithm B. */
|
||||
|
||||
/* Heuristics */
|
||||
|
||||
int HEURordmode; /* 0 = earliest, 1 = latest, 2 = difference */
|
||||
int HEURordmin; /* 0 = smaller is better, 1 = bigger is better */
|
||||
int HEURordrnd; /* 1 = randomly shuffle (to break ties) */
|
||||
int HEURtime; /* 0 = earliest, 1 = latest, 2 = all */
|
||||
int HEURops; /* 0 = first, 1 = all */
|
||||
int HEURchoice; /* 0 = random, 1 = weight */
|
||||
int HEURactions; /* How many suggested actions found? */
|
||||
int HEURactionchoice; /* choose action 0 = randomly, 1 = minimal time stamp */
|
||||
int HEURactiondepthlimit;
|
||||
|
||||
int stats_longest_learned;
|
4
makedate
Executable file
4
makedate
Executable file
@ -0,0 +1,4 @@
|
||||
rm -f zDATE zPRINTDATE
|
||||
date '+ %d/%m/20%y %H:%M:%S");' > zDATE
|
||||
cat zPREF zDATE > zPRINTDATE
|
||||
rm -f zDATE
|
1867
operators.c
Normal file
1867
operators.c
Normal file
File diff suppressed because it is too large
Load Diff
167
operators.h
Normal file
167
operators.h
Normal file
@ -0,0 +1,167 @@
|
||||
|
||||
/* 2012 (C) Jussi Rintanen */
|
||||
|
||||
/**************** compact ground formulae */
|
||||
|
||||
#ifdef CFMA
|
||||
|
||||
/* Compact formula representation:
|
||||
Formula is a pointer.
|
||||
If the lsb is 1, it is TRUE, FALSE or a literal.
|
||||
If the lsb is 0, it is a pointer to an integer array for con/disjunction.
|
||||
For conjunctions and disjunctions the first int is (length << 1) | cnj,
|
||||
where cnj == 1 if it is a conjunction and cnj = 0 if it is a disjunction.
|
||||
*/
|
||||
|
||||
typedef int **cfma;
|
||||
|
||||
/* If the lsb == 1, the 3 lsbs represent the type. */
|
||||
|
||||
#define cTRUEtag 1
|
||||
#define cFALSEtag 3
|
||||
#define cPATOMtag 5
|
||||
#define cNATOMtag 7
|
||||
|
||||
/* Literals are represented as (var << 3) | c?ATOM. */
|
||||
|
||||
#define cPATOM(v) ((cfma)(((v) << 3) | cPATOMtag))
|
||||
#define cNATOM(v) ((cfma)(((v) << 3) | cNATOMtag))
|
||||
#define cTRUE ((cfma)cTRUEtag)
|
||||
#define cFALSE ((cfma)cFALSEtag)
|
||||
|
||||
#endif
|
||||
|
||||
/**************** ground formulae */
|
||||
|
||||
typedef enum { patom, natom, conj, disj, TRUE, FALSE } fmatype;
|
||||
|
||||
typedef struct _fma {
|
||||
fmatype t;
|
||||
union {
|
||||
int a;
|
||||
struct _fmalist0 { struct _fma *hd; struct _fmalist0 *tl; } *juncts;
|
||||
};
|
||||
} fma;
|
||||
|
||||
|
||||
/***************** ground effects */
|
||||
|
||||
typedef struct _eff {
|
||||
fma *condition;
|
||||
#ifdef CFMA
|
||||
cfma ccondition;
|
||||
#endif
|
||||
int *effectlits;
|
||||
struct _eff *tl;
|
||||
} eff;
|
||||
|
||||
typedef struct _fmalist { fma *hd; struct _fmalist* tl; } fmalist;
|
||||
|
||||
fmalist *fmacons(fma *,fmalist *);
|
||||
|
||||
fma *Fconj(fmalist *);
|
||||
fma *Fdisj(fmalist *);
|
||||
fma *Fconj2(fma *,fma *);
|
||||
fma *Fdisj2(fma *,fma *);
|
||||
fma *Fatom(int);
|
||||
fma *Fnatom(int);
|
||||
fma *Fneg(fma *);
|
||||
fma *Fimpl(fma *,fma *);
|
||||
fma *Ftrue();
|
||||
fma *Ffalse();
|
||||
|
||||
typedef struct _action {
|
||||
int *name;
|
||||
fma *precon;
|
||||
#ifdef CFMA
|
||||
cfma cprecon;
|
||||
#endif
|
||||
eff effects;
|
||||
int cost;
|
||||
} action;
|
||||
|
||||
int nOfActions;
|
||||
int maxActions;
|
||||
action *actions;
|
||||
|
||||
int disjunctivep(fma *);
|
||||
void initactions();
|
||||
|
||||
int ptruep(fma *,int *); /* Test for truth of a formula in a state. */
|
||||
int execute(int,int *,int *); /* Execute an action. */
|
||||
void executeNOprecon(int,int *,int *); /* Execute an action without testin precondition. */
|
||||
|
||||
int fprintactionname(FILE *,int);
|
||||
int printactionname(int);
|
||||
int fprintactionnameIPC(FILE *,int);
|
||||
int printactionnameIPC(int);
|
||||
void printaction(int);
|
||||
void printfma(fma *);
|
||||
|
||||
typedef enum { STRIPS, Conjunctive, GeneralPDDL } syntacticclass;
|
||||
|
||||
syntacticclass actionclass(int);
|
||||
|
||||
syntacticclass goalclass();
|
||||
|
||||
int *initialstate;
|
||||
fma *goal;
|
||||
int goalisdisjunctive;
|
||||
|
||||
void simplifyoperators();
|
||||
void simplifyoperatorsstatic();
|
||||
|
||||
ordintset *effectoccP; /* operators in which var is a positive effect */
|
||||
ordintset *effectoccN; /* operators in which var is a negative effect */
|
||||
ordintset *forcedeffectoccP; /* operators in which var is a positive effect */
|
||||
ordintset *forcedeffectoccN; /* operators in which var is a negative effect */
|
||||
|
||||
|
||||
ordintset *preconoccN; /* operators in which var is negative in precondition */
|
||||
ordintset *preconoccP; /* operators in which var is positive in precondition */
|
||||
|
||||
ordintset *condocc; /* operators in which var occurs in a condition for effect */
|
||||
|
||||
ordintset *forcedeffectsP; /* variables the operator always makes true */
|
||||
ordintset *forcedeffectsN; /* variables the operator always makes false */
|
||||
|
||||
ordintset *preconP; /* variable that must be true for operator */
|
||||
ordintset *preconN; /* variable that must be false for operator */
|
||||
|
||||
/* Same as preconP and preconN, but including lits inferred with invariants. */
|
||||
ordintset *necessarypreconP; /* variable that must be true for operator */
|
||||
ordintset *necessarypreconN; /* variable that must be false for operator */
|
||||
|
||||
ordintset *necessarypreconofP; /* operators in which atom is a nec precon */
|
||||
ordintset *necessarypreconofN; /* operators in which atom is a nec precon */
|
||||
|
||||
int canmaketrue(int,int);
|
||||
int isaffectedby(int,int);
|
||||
int opaffects(int,int);
|
||||
int opaffectsinstate(int *,int,int);
|
||||
int parallel(int,int);
|
||||
int Lparallel(int,int);
|
||||
|
||||
void findoccurrences();
|
||||
|
||||
void sortactions();
|
||||
|
||||
void collectliterals(ordintset,int);
|
||||
|
||||
void eliminatestaticvariables();
|
||||
|
||||
void mergecontras();
|
||||
|
||||
int **AeffectoccP; /* operators in which var is a positive effect */
|
||||
int **AeffectoccN; /* operators in which var is a negative effect */
|
||||
int **ApreconP; /* variable that must be true for operator */
|
||||
int **ApreconN; /* variable that must be false for operator */
|
||||
int **AforcedeffectsP; /* variables the operator always makes true */
|
||||
int **AforcedeffectsN; /* variables the operator always makes false */
|
||||
int **AnecessarypreconP; /* variable that must be true for operator */
|
||||
int **AnecessarypreconN; /* variable that must be false for operator */
|
||||
int **ApreconoccN; /* operators in which var is negative in precondition */
|
||||
int **ApreconoccP; /* operators in which var is positive in precondition */
|
||||
int **Acondocc; /* operators in which var occurs in a condition for effect */
|
||||
|
||||
void constructoperatorarrays();
|
291
ordintsets.c
Normal file
291
ordintsets.c
Normal file
@ -0,0 +1,291 @@
|
||||
|
||||
/* 2010 (C) Jussi Rintanen */
|
||||
|
||||
#include "asyntax.h"
|
||||
#include "ordintsets.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
intlist *freeels = NULL;
|
||||
|
||||
inline intlist *OScons(int v,intlist *l) {
|
||||
intlist *tmp;
|
||||
if(freeels != NULL) {
|
||||
tmp = freeels;
|
||||
freeels = (intlist *)(freeels->tl);
|
||||
} else {
|
||||
tmp = (intlist *)malloc(sizeof(struct _intlist));
|
||||
}
|
||||
tmp->hd = v;
|
||||
tmp->tl = l;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* Free a cons pair to be used by OScons later. */
|
||||
|
||||
inline void OSfree(intlist *l) {
|
||||
l->tl = freeels;
|
||||
freeels = l;
|
||||
}
|
||||
|
||||
/* Really release all cons pairs allocated with OScons and freed by OSfree. */
|
||||
|
||||
void OSreleasefree() {
|
||||
intlist *l,*tmp;
|
||||
l = freeels;
|
||||
while(l != NULL) {
|
||||
tmp = l;
|
||||
l = l->tl;
|
||||
free(tmp);
|
||||
}
|
||||
freeels = NULL;
|
||||
}
|
||||
|
||||
ordintset OScreate() {
|
||||
ordintset tmp;
|
||||
tmp = (ordintset)malloc(sizeof(struct _ordintset));
|
||||
tmp->nOfEls = 0;
|
||||
tmp->elements = NULL;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
ordintset OScreateSize(int i) { return OScreate(); }
|
||||
|
||||
inline int OScard(ordintset s) {
|
||||
return s->nOfEls;
|
||||
}
|
||||
|
||||
inline int OSemptyp(ordintset s) {
|
||||
return (s->nOfEls == 0);
|
||||
}
|
||||
|
||||
inline void OSmakeempty(ordintset s) {
|
||||
intlist *l,*tmp;
|
||||
s->nOfEls = 0;
|
||||
l = s->elements;
|
||||
s->elements = NULL;
|
||||
while(l != NULL) {
|
||||
tmp = l;
|
||||
l = l->tl;
|
||||
OSfree(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
inline void OSinsert(int v,ordintset s) {
|
||||
intlist **prev,*l;
|
||||
|
||||
prev = &(s->elements);
|
||||
l = s->elements;
|
||||
while(l != NULL && l->hd < v) {
|
||||
prev = &(l->tl);
|
||||
l = l->tl;
|
||||
}
|
||||
|
||||
if(l != NULL && l->hd == v) return;
|
||||
|
||||
*prev = OScons(v,l);
|
||||
s->nOfEls += 1;
|
||||
}
|
||||
|
||||
inline void OSremove(int v,ordintset s) {
|
||||
printf("ERROR: not implemented\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
inline void OSremoveSet(ordintset s1,ordintset s2) {
|
||||
intlist *l1,*l2,**prev,*tmp;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("REMOVE "); OSprint(s1);
|
||||
printf("FROM "); OSprint(s2);
|
||||
#endif
|
||||
|
||||
l1 = s1->elements;
|
||||
l2 = s2->elements;
|
||||
|
||||
prev = &(s2->elements);
|
||||
|
||||
while(l1 != NULL) {
|
||||
while(l2 != NULL && l1->hd > l2->hd) { /* Find location for element. */
|
||||
prev = &(l2->tl);
|
||||
l2 = l2->tl;
|
||||
}
|
||||
|
||||
if(l2 == NULL) break;
|
||||
if(l1->hd == l2->hd) { /* Something to remove */
|
||||
tmp = l2;
|
||||
*prev = l2->tl;
|
||||
s2->nOfEls -= 1;
|
||||
l2 = l2->tl;
|
||||
OSfree(tmp);
|
||||
}
|
||||
l1 = l1->tl;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("TO GET "); OSprint(s2);
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void OS2removeSet(ordintset s1,ordintset s2) {
|
||||
intlist *l1,*l2,**prev,*tmp;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("REMOVE "); OSprint(s1);
|
||||
printf("FROM "); OSprint(s2);
|
||||
#endif
|
||||
|
||||
l1 = s1->elements;
|
||||
l2 = s2->elements;
|
||||
|
||||
prev = &(s2->elements);
|
||||
|
||||
while(l1 != NULL) {
|
||||
while(l2 != NULL && l1->hd > l2->hd) { /* Find location for element. */
|
||||
prev = &(l2->tl);
|
||||
l2 = l2->tl;
|
||||
}
|
||||
|
||||
if(l2 == NULL) break;
|
||||
if(l1->hd == l2->hd) {
|
||||
tmp = l2;
|
||||
*prev = l2->tl;
|
||||
s2->nOfEls -= 1;
|
||||
l2 = l2->tl;
|
||||
OSfree(tmp);
|
||||
}
|
||||
l1 = l1->tl;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("TO GET "); OSprint(s2);
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Intersect set s1 with s2: s1 := s1 /\ s2 */
|
||||
|
||||
inline void OSintersect(ordintset s1,ordintset s2) {
|
||||
intlist *l1,*l2,**prev,*tmp;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("INTERSECT "); OSprint(s1);
|
||||
printf("WITH "); OSprint(s2);
|
||||
#endif
|
||||
|
||||
l1 = s1->elements;
|
||||
l2 = s2->elements;
|
||||
|
||||
prev = &(s1->elements);
|
||||
|
||||
while(l1 != NULL) {
|
||||
while((l2 != NULL) && (l1->hd > l2->hd)) { /* Skip elements not in l1. */
|
||||
l2 = l2->tl;
|
||||
}
|
||||
|
||||
if((l2 != NULL) && (l1->hd == l2->hd)) { /* Retain element. */
|
||||
|
||||
prev = &(l1->tl);
|
||||
l1 = l1->tl;
|
||||
l2 = l2->tl;
|
||||
|
||||
} else { /* Remove the first element of l1. */
|
||||
|
||||
tmp = l1;
|
||||
*prev = l1->tl;
|
||||
s1->nOfEls -= 1;
|
||||
l1 = l1->tl;
|
||||
OSfree(tmp);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("TO GET "); OSprint(s1);
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
inline void OSaddelementsSTUPID(ordintset s1,ordintset s2) {
|
||||
intlist *l1;
|
||||
l1 = s1->elements;
|
||||
while(l1 != NULL) {
|
||||
OSinsert(l1->hd,s2);
|
||||
l1 = l1->tl;
|
||||
}
|
||||
}
|
||||
|
||||
inline void OSaddelements(ordintset s1,ordintset s2) {
|
||||
intlist *l1,*l2,**prev,*tmp;
|
||||
|
||||
// printf("ADD "); OSprint(s1);
|
||||
// printf("TO "); OSprint(s2);
|
||||
|
||||
l1 = s1->elements;
|
||||
l2 = s2->elements;
|
||||
|
||||
prev = &(s2->elements);
|
||||
|
||||
while(l1 != NULL) {
|
||||
|
||||
while(l2 != NULL && l1->hd > l2->hd) { /* Find location for element. */
|
||||
prev = &(l2->tl);
|
||||
l2 = l2->tl;
|
||||
}
|
||||
|
||||
if(l2 == NULL || l1->hd < l2->hd) {
|
||||
tmp = OScons(l1->hd,l2);
|
||||
*prev = tmp;
|
||||
prev = &(tmp->tl);
|
||||
s2->nOfEls += 1;
|
||||
}
|
||||
l1 = l1->tl;
|
||||
}
|
||||
|
||||
// printf("TO GET "); OSprint(s2);
|
||||
// printf("\n");
|
||||
}
|
||||
|
||||
inline int OSmember(int v,ordintset s) {
|
||||
intlist *l;
|
||||
l = s->elements;
|
||||
while(l != NULL) {
|
||||
if(l->hd < v) {
|
||||
l = l->tl;
|
||||
} else {
|
||||
if(l->hd == v) return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Iterator */
|
||||
|
||||
inline void OSstart(ordintset s,intlist **iterate) {
|
||||
*iterate = s->elements;
|
||||
}
|
||||
|
||||
inline int OSnext(int *v,intlist **iterate) {
|
||||
if(*iterate != NULL) {
|
||||
*v = (*iterate)->hd;
|
||||
*iterate = (*iterate)->tl;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void OSprint(ordintset s) {
|
||||
intlist *l;
|
||||
l = s->elements;
|
||||
while(l != NULL) {
|
||||
printf(" %i",l->hd);
|
||||
l = l->tl;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
26
ordintsets.h
Normal file
26
ordintsets.h
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
/* 2010 (C) Jussi Rintanen */
|
||||
|
||||
typedef struct _ordintset {
|
||||
int nOfEls;
|
||||
intlist *elements;
|
||||
} *ordintset;
|
||||
|
||||
ordintset OScreate();
|
||||
ordintset OScreateSize(int);
|
||||
int OScard(ordintset);
|
||||
int OSemptyp(ordintset);
|
||||
void OSmakeempty();
|
||||
void OSinsert(int,ordintset);
|
||||
void OSremove(int,ordintset);
|
||||
void OSremoveSet(ordintset,ordintset);
|
||||
void OS2removeSet(ordintset,ordintset);
|
||||
void OSaddelements(ordintset,ordintset); /* Add the elements of 1st to 2nd. */
|
||||
void OSintersect(ordintset,ordintset);
|
||||
int OSmember(int,ordintset);
|
||||
void OSreleasefree();
|
||||
|
||||
void OSstart(ordintset,intlist **);
|
||||
int OSnext(int *,intlist **);
|
||||
|
||||
void OSprint(ordintset);
|
211
parser.y
Normal file
211
parser.y
Normal file
@ -0,0 +1,211 @@
|
||||
|
||||
/* 2010 (C) Jussi Rintanen */
|
||||
|
||||
%{
|
||||
|
||||
#include "stdio.h"
|
||||
#include "main.h"
|
||||
#include "asyntax.h"
|
||||
|
||||
#define YYERROR_VERBOSE
|
||||
|
||||
void rparen(char *);
|
||||
|
||||
int COST;
|
||||
|
||||
%}
|
||||
|
||||
%define parse.error verbose
|
||||
|
||||
%union {
|
||||
int i;
|
||||
intlist *intlistp;
|
||||
atomlist *atomlistp;
|
||||
atom *atomp;
|
||||
Sfma *Sfmap;
|
||||
Sfmalist *Sfmalistp;
|
||||
Seff *Seffp;
|
||||
Sefflist *Sefflistp;
|
||||
typedvarlist *typedvarlistp;
|
||||
}
|
||||
|
||||
/* all of the terminal grammar symbols (tokens recognized
|
||||
by the lexical analyzer) */
|
||||
|
||||
%left RPAREN LPAREN DASH rwDEFINE rwACTION rwPARAMS rwEFFECT rwPRECOND rwPREDICATES rwREQUIREMENTS rwTYPES rwOBJECTS rwINIT rwGOAL rwDOMAIN rwTYPING rwAND rwOR rwWHEN rwNOT rwIMPLY rwFORALL rwPROBLEM EQUA rwEXISTS rwLENGTH rwCONSTANTS rwEITHER rwINCREASE rwMETRIC rwMINIMIZE
|
||||
|
||||
%left <i> ID VAR INT
|
||||
|
||||
%term LPAREN RPAREN DASH EQUA rwAND rwOR rwNOT rwIMPLY rwPRECOND rwDEFINE rwDOMAIN rwPROBLEM rwPREDICATES rwFUNCTIONS rwREQUIREMENTS rwACTION rwPARAMS rwEFFECT rwOBJECTS rwTYPES rwWHEN rwFORALL rwEXISTS rwLENGTH rwGOAL rwINIT rwCONSTANTS
|
||||
|
||||
|
||||
/* What nonterminals return? */
|
||||
|
||||
%type <void> begin domain domaindefs domaindef actdef actdefs problem defs def typedvarlist typedatoms costexpr
|
||||
%type <atomp> atom
|
||||
%type <Sfmap> fma
|
||||
%type <Sfmalistp> fmas
|
||||
%type <Seffp> effect
|
||||
%type <Sefflistp> effects
|
||||
%type <intlistp> idlist varlist varidlist
|
||||
%type <atomlistp> atomlist
|
||||
%type <i> varid
|
||||
%type <i> numexpr
|
||||
%type <typedvarlistp> opvars opvar opvarlist objectlist
|
||||
|
||||
%start begin
|
||||
%%
|
||||
|
||||
begin : domain problem
|
||||
;
|
||||
|
||||
idlist : ID idlist { $$ = intcons($1,$2); }
|
||||
| { $$ = EMPTYLIST; }
|
||||
;
|
||||
|
||||
costexpr : LPAREN EQUA numexpr numexpr RPAREN { }
|
||||
;
|
||||
|
||||
atom : LPAREN ID varidlist { rparen("term"); } RPAREN { $$ = newatom($2,$3); }
|
||||
;
|
||||
|
||||
atomlist : atomlist atom { $$ = atomcons($2,$1); }
|
||||
| atomlist costexpr { $$ = $1; }
|
||||
| { $$ = EMPTYLIST; }
|
||||
;
|
||||
|
||||
varid : VAR { $$ = $1; }
|
||||
| ID { $$ = $1; }
|
||||
;
|
||||
|
||||
varidlist : varid varidlist { $$ = intcons($1,$2); }
|
||||
| { $$ = EMPTYLIST; }
|
||||
;
|
||||
|
||||
/* PDDL definitions start here. */
|
||||
|
||||
domain : LPAREN rwDEFINE LPAREN rwDOMAIN ID { rparen("domain"); } RPAREN domaindefs { rparen("domain body"); } RPAREN { storedomain($5); }
|
||||
;
|
||||
|
||||
domaindefs : domaindefs domaindef
|
||||
| { }
|
||||
;
|
||||
|
||||
domaindef : LPAREN rwPREDICATES typedatoms { rparen(":predicates"); } RPAREN { storepredicates(); }
|
||||
| LPAREN rwREQUIREMENTS idlist { rparen(":requirements"); } RPAREN { checkrequirements($3); }
|
||||
| LPAREN rwCONSTANTS objectlist { rparen(":constants"); } RPAREN { storeconstants($3); }
|
||||
| LPAREN rwFUNCTIONS functiondecls { rparen(":functions"); } RPAREN { }
|
||||
| LPAREN rwTYPES objectlist { rparen(":types"); } RPAREN { storetypes($3); }
|
||||
| LPAREN rwACTION { COST = 0; } ID actdefs { rparen(":action"); } RPAREN { addactioncost(COST); addnewaction($4); }
|
||||
;
|
||||
|
||||
actdefs : actdef actdefs
|
||||
| actdef
|
||||
;
|
||||
|
||||
actdef : rwPARAMS LPAREN opvars { rparen(":action definitions"); } RPAREN { addactionparameters($3); }
|
||||
| rwPRECOND fma { addactionprecond($2); }
|
||||
| rwEFFECT effect { addactioneffect($2); }
|
||||
;
|
||||
|
||||
opvars : varlist { $$ = withtype(UNIVTYPE,$1); }
|
||||
| opvarlist { $$ = $1; }
|
||||
| { $$ = EMPTYLIST; }
|
||||
;
|
||||
|
||||
varlist : VAR varlist { $$ = intcons($1,$2); }
|
||||
| VAR { $$ = intcons($1, EMPTYLIST); }
|
||||
;
|
||||
|
||||
opvarlist : opvar opvarlist { $$ = TVappend($1,$2); }
|
||||
| opvar { $$ = $1; }
|
||||
;
|
||||
|
||||
opvar : varlist DASH ID { $$ = withtype($3,$1); }
|
||||
;
|
||||
|
||||
|
||||
problem : LPAREN rwDEFINE LPAREN rwPROBLEM ID { rparen(":problem"); } RPAREN defs { rparen("problem definition"); } RPAREN { addproblem($5); }
|
||||
;
|
||||
|
||||
defs : defs LPAREN def { rparen("problem definitions"); } RPAREN { }
|
||||
| LPAREN def { rparen("problem definitions"); } RPAREN { }
|
||||
;
|
||||
|
||||
def : rwDOMAIN ID { checkdomain($2); }
|
||||
| rwOBJECTS objectlist { storeobjects($2); }
|
||||
| rwINIT atomlist { storeinit($2); }
|
||||
| rwGOAL fma { storegoal($2); }
|
||||
| rwMETRIC rwMINIMIZE atomlist { }
|
||||
;
|
||||
|
||||
|
||||
objectlist : idlist DASH ID objectlist { $$ = TVappend(withtype($3,$1),$4); }
|
||||
| idlist { $$ = withtype(UNIVTYPE,$1); }
|
||||
;
|
||||
|
||||
typedvarlist : VAR DASH ID typedvarlist { }
|
||||
| VAR DASH LPAREN rwEITHER ID idlist { rparen("typed variable list"); } RPAREN typedvarlist { }
|
||||
| VAR typedvarlist { }
|
||||
| { }
|
||||
;
|
||||
|
||||
typedatoms : typedatoms LPAREN ID typedvarlist { rparen("typed atom list"); } RPAREN { }
|
||||
| { }
|
||||
;
|
||||
|
||||
functiondecls : functiondecl functiondecls { }
|
||||
| { }
|
||||
;
|
||||
|
||||
functiondecl : tdecl DASH ID { }
|
||||
| tdecl { }
|
||||
;
|
||||
|
||||
tdecl : LPAREN ID typedvarlist { rparen("function list"); } RPAREN
|
||||
;
|
||||
|
||||
|
||||
|
||||
fma : LPAREN rwAND { rparen("empty conjunction"); } RPAREN { $$ = Strue(); }
|
||||
| LPAREN rwAND fmas { rparen("conjunction"); } RPAREN { $$ = Sconjunction($3); }
|
||||
| LPAREN rwWHEN fma fma { rparen("when"); } RPAREN { $$ = Sconjunction(Sfmacons(Sneg($3),Sfmacons($4,EMPTYLIST))); }
|
||||
| LPAREN rwOR fmas { rparen("disjunction"); } RPAREN { $$ = Sdisjunction($3); }
|
||||
| LPAREN rwIMPLY fma fma { rparen("imply"); } RPAREN { $$ = Sdisjunction(Sfmacons(Sneg($3),Sfmacons($4,EMPTYLIST))); }
|
||||
| LPAREN rwNOT fma { rparen("not"); } RPAREN { $$ = Sneg($3); }
|
||||
| atom { $$ = Satom($1); }
|
||||
| LPAREN EQUA varid varid { rparen("equality"); } RPAREN { $$ = SfmaEQ($3,$4); }
|
||||
| LPAREN rwFORALL LPAREN opvars RPAREN fma { rparen("forall"); } RPAREN { $$ = Sfmaforall($4,$6); }
|
||||
| LPAREN rwEXISTS LPAREN opvars RPAREN fma { rparen("exists"); } RPAREN { $$ = Sfmaforsome($4,$6); }
|
||||
;
|
||||
|
||||
fmas : fmas fma { $$ = Sfmacons($2,$1); }
|
||||
| fma { $$ = Sfmacons($1,EMPTYLIST); }
|
||||
;
|
||||
|
||||
effects : effects effect { $$ = Seffcons($2,$1); }
|
||||
| effect { $$ = Seffcons($1,EMPTYLIST); }
|
||||
;
|
||||
|
||||
numexpr : atom { $$ = 0; }
|
||||
| INT { $$ = $1; }
|
||||
;
|
||||
|
||||
effect: LPAREN rwAND { rparen("empty conjunction"); } RPAREN { $$ = Seffconjunction(EMPTYLIST); }
|
||||
| LPAREN rwAND effects { rparen("compound effect"); } RPAREN { $$ = Seffconjunction($3); }
|
||||
| LPAREN rwWHEN fma effect { rparen("when"); } RPAREN { $$ = Seffwhen($3,$4); }
|
||||
| LPAREN rwFORALL LPAREN opvars RPAREN effect { rparen("forall"); } RPAREN { $$ = Seffforall($4,$6); }
|
||||
| atom { $$ = SPeffatom($1); }
|
||||
| LPAREN rwNOT atom { rparen("not"); } RPAREN { $$ = SNeffatom($3); }
|
||||
| LPAREN rwINCREASE atom numexpr { rparen("increase"); } RPAREN { $$ = Seffconjunction(NULL); COST = $4; }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
void parseerror(char *s) {
|
||||
errorstring = s;
|
||||
}
|
||||
|
||||
void rparen(char *s) {
|
||||
errorstring = s;
|
||||
}
|
291
printplan.c
Normal file
291
printplan.c
Normal file
@ -0,0 +1,291 @@
|
||||
|
||||
/* 2012 (C) Jussi Rintanen, jrintanen.jr@gmail.com */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "interface.h"
|
||||
#include "main.h"
|
||||
#include "asyntax.h"
|
||||
#include "tables.h"
|
||||
#include "ordintsets.h"
|
||||
#include "operators.h"
|
||||
|
||||
#define IPC 1
|
||||
#define FIELD 35
|
||||
|
||||
/* Print atoms true in a state. */
|
||||
|
||||
void printstate(satinstance sati,int *state) {
|
||||
int i;
|
||||
for(i=0;i<sati->nOfSVars;i++) {
|
||||
if(state[i]) { printf(" "); printatomi(i); }
|
||||
}
|
||||
}
|
||||
|
||||
/* Print a tabular representation of the values of state variables and
|
||||
operators at different time points. */
|
||||
|
||||
void printplanT(satinstance sati) {
|
||||
int i,j,len;
|
||||
for(j=0;j<FIELD;j++) printf("_");
|
||||
for(j=0;j<sati->nOfTPoints;j++) printf("%i",j%10);
|
||||
printf("\n");
|
||||
for(i=0;i<nOfAtoms;i++) {
|
||||
len = printatomi(i);
|
||||
for(j=0;j<FIELD-len;j++) printf("_");
|
||||
for(j=0;j<sati->nOfTPoints;j++) {
|
||||
switch(varvalue(sati,TVAR(i,j))) {
|
||||
case 0: printf("."); break;
|
||||
case 1: printf("T"); break;
|
||||
default: printf(" "); break;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
for(i=0;i<nOfActions;i++) {
|
||||
len = printactionname(i);
|
||||
for(j=0;j<FIELD-len;j++) printf("_");
|
||||
for(j=0;j<sati->nOfTPoints-1;j++) {
|
||||
switch(varvalue(sati,TACT(i,j))) {
|
||||
case 0: printf("."); break;
|
||||
case 1: printf("T"); break;
|
||||
default: printf(" "); break;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Print a tabular representation of the values of state variables
|
||||
at different time points. */
|
||||
|
||||
void printplanV(satinstance sati) {
|
||||
int i,j,len;
|
||||
for(j=0;j<FIELD;j++) printf("_");
|
||||
for(j=0;j<sati->nOfTPoints;j++) printf("%i",j%10);
|
||||
printf("\n");
|
||||
for(i=0;i<nOfAtoms;i++) {
|
||||
len = printatomi(i);
|
||||
for(j=0;j<FIELD-len;j++) printf("_");
|
||||
for(j=0;j<sati->nOfTPoints;j++) {
|
||||
switch(varvalue(sati,TVAR(i,j))) {
|
||||
case 0: printf("."); break;
|
||||
case 1: printf("T"); break;
|
||||
default: printf(" "); break;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Print the plan as a sequence of operators.
|
||||
|
||||
(Test also that the plan actually is a solution to the planning problem.)
|
||||
|
||||
*/
|
||||
|
||||
void copystate(satinstance sati,int *s1,int *s2) {
|
||||
int i;
|
||||
for(i=0;i<sati->nOfSVars;i++) s2[i] = s1[i];
|
||||
}
|
||||
|
||||
#define MAXSTEPSIZE 50000
|
||||
|
||||
void fprintplan(FILE *f,satinstance sati) {
|
||||
int pactions[MAXSTEPSIZE];
|
||||
int sactions[MAXSTEPSIZE];
|
||||
int substepcnt;
|
||||
int pcnt,toprint,round,naf,cnt;
|
||||
int t,i,j,actionsinplan;
|
||||
int state0[sati->nOfSVars],state1[sati->nOfSVars];
|
||||
int print_t;
|
||||
int cost;
|
||||
#ifdef IPC
|
||||
int print_a;
|
||||
#endif
|
||||
|
||||
cost = 0;
|
||||
actionsinplan = 0;
|
||||
print_t = 0;
|
||||
#ifdef IPC
|
||||
print_a = 0;
|
||||
#endif
|
||||
|
||||
for(i=0;i<sati->nOfSVars;i++) state0[i] = varvalue(sati,i);
|
||||
|
||||
copystate(sati,state0,state1);
|
||||
|
||||
for(t=0;t<sati->nOfTPoints-1;t++) {
|
||||
|
||||
/* Get action indices to pactions. */
|
||||
|
||||
pcnt = 0; /* How many actions in the current time point. */
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(f,"Actions at STEP %i: ",t);
|
||||
#endif
|
||||
|
||||
for(i=0;i<nOfActions;i++) {
|
||||
if(vartruep(sati,TACT(i,t))) {
|
||||
pactions[pcnt++] = i;
|
||||
if(pcnt >= MAXSTEPSIZE) {
|
||||
fprintf(stderr,"ERROR: max. step size %i exceeded. Recompile with increased MAXSTEPSIZE.\n",MAXSTEPSIZE);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
fprintactionname(f,i);
|
||||
#endif
|
||||
actionsinplan += 1;
|
||||
cost += actions[i].cost;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
toprint = pcnt;
|
||||
round = 0;
|
||||
|
||||
/* Find actions that don't affect any of the remaining actions. */
|
||||
|
||||
while(toprint) {
|
||||
|
||||
copystate(sati,state0,state1);
|
||||
|
||||
cnt = 0;
|
||||
|
||||
substepcnt = 0; /* Number of actions currently in the substep */
|
||||
|
||||
for(i=0;i<pcnt;i++) {
|
||||
if(pactions[i] == -1) continue;
|
||||
naf = 0;
|
||||
|
||||
for(j=0;j<pcnt;j++) {
|
||||
if(j==i) continue;
|
||||
if(pactions[j] == -1) continue;
|
||||
|
||||
if(opaffectsinstate(state1,pactions[i],pactions[j])) {
|
||||
#ifdef DEBUG
|
||||
printactionname(pactions[i]);
|
||||
printf(" %i affects %i ",pactions[i],pactions[j]);
|
||||
printactionname(pactions[j]);
|
||||
printf("\n");
|
||||
#endif
|
||||
naf = 1;
|
||||
break;
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
printactionname(pactions[i]);
|
||||
printf(" %i does NOT affect %i ",pactions[i],pactions[j]);
|
||||
printactionname(pactions[j]);
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(!naf) {
|
||||
toprint -= 1;
|
||||
cnt += 1;
|
||||
sactions[substepcnt++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Print the current substep. */
|
||||
|
||||
if(!flagIPCplans) {
|
||||
if(toprint == 0 && round == 0) {
|
||||
fprintf(f,"STEP %i:",t);
|
||||
} else {
|
||||
fprintf(f,"STEP %i.%i:",t,round);
|
||||
}
|
||||
}
|
||||
|
||||
for(j=0;j<substepcnt;j++) {
|
||||
|
||||
if(flagIPCplans) {
|
||||
#ifdef IPC
|
||||
fprintf(f,"%d : ",print_a++);
|
||||
#else
|
||||
fprintf(f,"%d : ",print_t);
|
||||
#endif
|
||||
fprintactionnameIPC(f,pactions[sactions[j]]);
|
||||
fprintf(f,"\n");
|
||||
} else {
|
||||
fprintf(f," ");
|
||||
fprintactionname(f,pactions[sactions[j]]);
|
||||
}
|
||||
|
||||
if(!execute(pactions[sactions[j]],state0,state1)) {
|
||||
fprintf(stderr,"ERROR: plan not executable!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pactions[sactions[j]] = -1;
|
||||
|
||||
}
|
||||
|
||||
if(cnt == 0) {
|
||||
fprintf(stderr,"ERROR: no actions in current round (%i)!\n",pcnt);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
copystate(sati,state1,state0);
|
||||
|
||||
print_t += 1;
|
||||
|
||||
if(!flagIPCplans) {
|
||||
fprintf(f,"\n");
|
||||
}
|
||||
|
||||
round += 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Test that the goal is indeed true in the resulting final state. */
|
||||
if(!ptruep(goal,state1)) {
|
||||
printfma(goal);
|
||||
printf("ERROR: goal not reached by the plan.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// printf("TERMINAL STATE:"); printstate(sati,state1); printf("\n");
|
||||
|
||||
printf("%i actions in the plan.\n",actionsinplan);
|
||||
if(cost) printf("Cost of the plan is %i.\n",cost);
|
||||
}
|
||||
|
||||
/* Print a literal in the textual form. */
|
||||
|
||||
void printUvar(int i) {
|
||||
if(i < nOfAtoms) {
|
||||
printatomi(i);
|
||||
} else if(i < nOfAtoms+nOfActions) {
|
||||
printactionname(i-nOfAtoms);
|
||||
} else {
|
||||
printf("AUX%i",i-nOfAtoms-nOfActions);
|
||||
}
|
||||
}
|
||||
|
||||
void printUlits(int *ptr) {
|
||||
while(*ptr != -1) {
|
||||
if(*ptr & 1) printf(" -"); else printf(" ");
|
||||
printUvar(VAR(*ptr));
|
||||
ptr = ptr + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void printTlit(satinstance sati,int l) {
|
||||
if(l&1) printf("-");
|
||||
if(planFrontend) {
|
||||
printf("%i:",VAR(l));
|
||||
printUvar(tvarvar(sati,VAR(l)));
|
||||
printf("@%i",tvartime(sati,VAR(l)));
|
||||
} else {
|
||||
printf("%i",VAR(l)+1);
|
||||
}
|
||||
}
|
8
printplan.h
Normal file
8
printplan.h
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
/* 2010 (C) Jussi Rintanen */
|
||||
|
||||
void fprintplan(FILE *,satinstance);
|
||||
void printplanT(satinstance); /* Print action and state variables. */
|
||||
void printplanV(satinstance); /* Print state variables only. */
|
||||
void printTlit(satinstance,int);
|
||||
void printUvar(int);
|
201
scc.c
Normal file
201
scc.c
Normal file
@ -0,0 +1,201 @@
|
||||
|
||||
/* 2012 (C) Jussi Rintanen, jrintanen.jr@gmail.com */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "asyntax.h"
|
||||
#include "ordintsets.h"
|
||||
#include "operators.h"
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#include "scc.h"
|
||||
|
||||
/**********************************************************************/
|
||||
/* Strong components of a graph */
|
||||
/**********************************************************************/
|
||||
|
||||
/* Compute strong components of the disabling graph. The arcs are not
|
||||
constructed explicitly, as computing them is expensive and most arcs
|
||||
would never be followed.
|
||||
The starting node is node number 0. The set of all nodes is
|
||||
{0,...,nOfNodes-1}. */
|
||||
|
||||
#define noDEBUG
|
||||
|
||||
int *NNdfnumber;
|
||||
int *NNstack;
|
||||
unsigned char *NNinstack;
|
||||
int *NNlowlink;
|
||||
|
||||
int NNptr,NNdf;
|
||||
int NNsingletons;
|
||||
|
||||
int maxSCCsize;
|
||||
|
||||
int nodecounter;
|
||||
|
||||
#define min(a,b) (((a)<(b))?(a):(b))
|
||||
|
||||
#define likely(expr) (__builtin_expect((expr),1))
|
||||
#define unlikely(expr) (__builtin_expect((expr),0))
|
||||
|
||||
inline int getnext(int *el,eff **efs,int **e,int **as1,int **as2) {
|
||||
|
||||
getfromas:
|
||||
|
||||
if(**as1 != -1) {
|
||||
*el = **as1;
|
||||
(*as1)++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(**as2 != -1) {
|
||||
*el = **as2;
|
||||
(*as2)++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
getfrompene:
|
||||
|
||||
if(**e != -1) {
|
||||
if((**e)&1) {
|
||||
*as1 = ApreconoccP[feVAR(**e)];
|
||||
} else {
|
||||
*as1 = ApreconoccN[feVAR(**e)];
|
||||
}
|
||||
*as2 = Acondocc[feVAR(**e)];
|
||||
*e = *e + 1;
|
||||
goto getfromas;
|
||||
}
|
||||
|
||||
if(*efs != NULL) {
|
||||
*e = (*efs)->effectlits;
|
||||
*efs = (*efs)->tl;
|
||||
goto getfrompene;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sccs NNtraverse(int i,sccs ac) {
|
||||
int j,current;
|
||||
|
||||
eff *efs;
|
||||
int *e;
|
||||
int *as1,*as2;
|
||||
int dummy;
|
||||
int el;
|
||||
|
||||
nodecounter = nodecounter + 1;
|
||||
|
||||
if((10*nodecounter / nOfActions) != (10*(nodecounter-1) / nOfActions)) {
|
||||
printf(" %i",(nodecounter * 10 / nOfActions)*10); fflush(stdout);
|
||||
}
|
||||
|
||||
NNdfnumber[i] = ++NNdf;
|
||||
NNlowlink[i] = NNdf;
|
||||
|
||||
NNstack[++NNptr] = i;
|
||||
NNinstack[i] = 1;
|
||||
|
||||
current = NNptr;
|
||||
|
||||
efs = &(actions[i].effects);
|
||||
|
||||
dummy = -1;
|
||||
|
||||
e = &dummy;
|
||||
|
||||
as1 = &dummy;
|
||||
as2 = &dummy;
|
||||
|
||||
/* Go through all neighbor CANDIDATES. */
|
||||
|
||||
while(getnext(&el,&efs,&e,&as1,&as2)) {
|
||||
|
||||
if(NNdfnumber[el] == -1 && parallel(i,el)) {
|
||||
ac = NNtraverse(el,ac);
|
||||
NNlowlink[i] = min(NNlowlink[i],NNlowlink[el]);
|
||||
} else {
|
||||
if(NNinstack[el] == 1 && NNlowlink[i] > NNdfnumber[el] && parallel(i,el)) {
|
||||
NNlowlink[i] = NNdfnumber[el];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(NNlowlink[i] == NNdfnumber[i]) { /* Found an SCC */
|
||||
sccs oldac;
|
||||
oldac = ac;
|
||||
ac = (sccs)statmalloc(405,sizeof(struct _scc));
|
||||
ac->NofEls = NNptr-current+1;
|
||||
ac->next = oldac;
|
||||
ac->els = (int *)statmalloc(406,ac->NofEls * sizeof(int));
|
||||
|
||||
if(ac->NofEls > maxSCCsize) maxSCCsize = ac->NofEls;
|
||||
|
||||
if(NNptr == current) NNsingletons += 1;
|
||||
|
||||
for(j=current;j<=NNptr;j++) ac->els[j-current] = NNstack[j];
|
||||
|
||||
if(flagShowInput) {
|
||||
printf("new SCC %i:",ac->NofEls);
|
||||
for(j=current;j<=NNptr;j++) printactionname(NNstack[j]); // printf(" %i",NNstack[j]);
|
||||
printf("\n");
|
||||
} else {
|
||||
if(debugOutput > 0 && NNptr != current) printf(" %i",NNptr-current+1);
|
||||
}
|
||||
|
||||
for(j=current;j<=NNptr;j++) NNinstack[NNstack[j]] = 0;
|
||||
NNptr = current-1;
|
||||
}
|
||||
return ac;
|
||||
}
|
||||
|
||||
int scc(int nOfNodes) {
|
||||
int i;
|
||||
sccs ac;
|
||||
|
||||
nodecounter = 0;
|
||||
|
||||
NNdf = -1;
|
||||
NNptr = -1;
|
||||
|
||||
if(debugOutput > 0) printf("Finding SCCs for %i nodes.\n",nOfNodes);
|
||||
|
||||
NNdfnumber = (int *)statmalloc(407,nOfNodes * sizeof(int));
|
||||
NNstack = (int *)statmalloc(408,nOfNodes * sizeof(int));
|
||||
NNinstack = (unsigned char *)statmalloc(409,nOfNodes * sizeof(unsigned char));
|
||||
NNlowlink = (int *)statmalloc(410,nOfNodes * sizeof(int));
|
||||
|
||||
NNsingletons = 0;
|
||||
|
||||
maxSCCsize = 0;
|
||||
|
||||
for(i=0;i<nOfNodes;i++) {
|
||||
NNdfnumber[i] = -1;
|
||||
NNinstack[i] = 0;
|
||||
}
|
||||
|
||||
ac = NULL;
|
||||
|
||||
printf("Disabling graph %c:",'%');
|
||||
|
||||
for(i=0;i<nOfNodes;i++)
|
||||
if(NNdfnumber[i] == -1) {
|
||||
ac = NNtraverse(i,ac);
|
||||
}
|
||||
|
||||
if(debugOutput > 0) printf(", %i singleton components\n",NNsingletons);
|
||||
|
||||
SCCS = ac;
|
||||
|
||||
free(NNdfnumber);
|
||||
free(NNstack);
|
||||
free(NNinstack);
|
||||
free(NNlowlink);
|
||||
|
||||
return maxSCCsize;
|
||||
}
|
12
scc.h
Normal file
12
scc.h
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
/* 2010 (C) Jussi Rintanen */
|
||||
|
||||
typedef struct _scc {
|
||||
int NofEls;
|
||||
int *els;
|
||||
struct _scc *next;
|
||||
} *sccs;
|
||||
|
||||
int scc(int);
|
||||
|
||||
sccs SCCS;
|
123
shortcuts.c
Normal file
123
shortcuts.c
Normal file
@ -0,0 +1,123 @@
|
||||
|
||||
/* 2012 (C) Jussi Rintanen, jrintanen.jr@gmail.com */
|
||||
|
||||
/* For every literal l1, identify unit-propagation consequences l2 for which
|
||||
the derivation involve non-binary clauses. These consequences l1 !-UP l2
|
||||
are useful for two reasons.
|
||||
1. It is not necessarily the case that -l2 !-UP -l1, and hence with
|
||||
the new clause -l1 V l2 we get l2 !-UP l1 as a new consequence.
|
||||
2. The clause learning algorithm avoids the use of a potentially long
|
||||
non-binary clauses, sometimes leading to much shorter learned clauses
|
||||
and much faster learning and unit propagation.
|
||||
*/
|
||||
|
||||
#define noHARDDEBUG
|
||||
#define noSHOWIT
|
||||
|
||||
void shortcutprobe(satinstance sati,int l) {
|
||||
int i,l2;
|
||||
PTRINT reason;
|
||||
|
||||
#ifdef HARDDEBUG
|
||||
printf("--------------------------------------------------------------\n");
|
||||
#endif
|
||||
|
||||
for(i=0;i<sati->nOfVars;i++) {
|
||||
int flag;
|
||||
flag=0;
|
||||
if(!varunsetp(sati,i)) {
|
||||
printf("INCORRECTLY ALREADY SET: %i",i); printTlit(sati,PLIT(i));
|
||||
flag = 1;
|
||||
}
|
||||
assert(flag==0);
|
||||
}
|
||||
|
||||
setUPstacktop(sati,-1); /* Drop the input unit clauses from the stack. */
|
||||
sati->dlevel = 0;
|
||||
|
||||
sati->declevels[0] = 0;
|
||||
|
||||
#ifdef HARDDEBUG
|
||||
printf("Trying ");
|
||||
printTlit(sati,l);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
simpleaddtoqueue(sati,l,REASON_DECISION,0);
|
||||
|
||||
if(propagate(sati)) {
|
||||
// Literal cannot be true.
|
||||
#ifdef SHOWIT
|
||||
printf("CONTRADICTION WITH ");
|
||||
printTlit(sati,l);
|
||||
printf("\n");
|
||||
#endif
|
||||
undo_assignments_until_level_NOHEAP(sati,0);
|
||||
return;
|
||||
}
|
||||
|
||||
// printf("PROPAGATED\n");
|
||||
|
||||
for(i=1;i<sati->endunitstack;i++) { // Go through inferred literals.
|
||||
|
||||
l2 = sati->unitstack[i];
|
||||
|
||||
reason = LITREASON(l2);
|
||||
|
||||
#ifdef HARDDEBUG
|
||||
printf("Checking %i:",i); printTlit(sati,l2);
|
||||
printf(" REASON: ");
|
||||
if(reason == REASON_INPUT) printf("INPUT");
|
||||
else if(reason == REASON_DECISION) printf("DECISION");
|
||||
else if((reason&1)==0) printf(" LONG CLAUSE");
|
||||
else printTlit(sati,reason >> 1);
|
||||
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
if((reason & 3) == 0 && clauselen((int *)reason) > 3) { // Reason is a long clause?
|
||||
// Store the new binary literal for later use.
|
||||
if(nofshortcutclauses+1 >= maxshortcutclauses) {
|
||||
maxshortcutclauses = maxshortcutclauses * 2;
|
||||
shortcutclauses = (shortcutclause *)realloc(shortcutclauses,
|
||||
maxshortcutclauses * sizeof(shortcutclause));
|
||||
}
|
||||
|
||||
shortcutclauses[nofshortcutclauses].l1 = NEG(l) % (2 * sati->nOfVarsPerTime);
|
||||
shortcutclauses[nofshortcutclauses].l2 = l2 % (2 * sati->nOfVarsPerTime);
|
||||
shortcutclauses[nofshortcutclauses++].tdiff = tvartime(sati,VAR(l2))-tvartime(sati,VAR(l));
|
||||
|
||||
#ifdef SHOWIT
|
||||
printf("INFER CLAUSE: ");
|
||||
printTlit(sati,shortcutclauses[nofshortcutclauses-1].l1);
|
||||
printf(" V ");
|
||||
printlit(shortcutclauses[nofshortcutclauses-1].l2);
|
||||
printf("@%i (through length %i)\n",shortcutclauses[nofshortcutclauses-1].tdiff,clauselen((int *)reason));
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
undo_assignments_until_level_NOHEAP(sati,0);
|
||||
|
||||
for(i=0;i<sati->nOfVars;i++)
|
||||
if(!varunsetp(sati,i)) {
|
||||
printf("INCORRECTLY REMAINS SET: %i",i); printTlit(sati,PLIT(i));
|
||||
assert(1==0);
|
||||
}
|
||||
}
|
||||
|
||||
void shortcuts(satinstance sati) {
|
||||
int p;
|
||||
|
||||
maxshortcutclauses = 100000;
|
||||
nofshortcutclauses = 0;
|
||||
shortcutclauses = (shortcutclause *)malloc(maxshortcutclauses * sizeof(shortcutclause));
|
||||
|
||||
for(p=0;p<sati->nOfSVars;p++) {
|
||||
shortcutprobe(sati,PLIT(varwithtime(sati,p,flagShortCutHorizon)));
|
||||
shortcutprobe(sati,NLIT(varwithtime(sati,p,flagShortCutHorizon)));
|
||||
}
|
||||
#ifdef SHOWIT
|
||||
printf("INFERRED %i SHORTCUT CLAUSES.\n",nofshortcutclauses);
|
||||
#endif
|
||||
}
|
296
tables.c
Normal file
296
tables.c
Normal file
@ -0,0 +1,296 @@
|
||||
|
||||
/* 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];
|
||||
}
|
||||
}
|
39
tables.h
Normal file
39
tables.h
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
/* 2010 (C) Jussi Rintanen */
|
||||
|
||||
/* Symboltable for IDs and VARs in lexer */
|
||||
|
||||
typedef struct _stbucket {
|
||||
int index;
|
||||
char staticpredicate;
|
||||
char *s;
|
||||
struct _stbucket *next;
|
||||
} stentry;
|
||||
|
||||
#define MAXBUCKETS 0x20000
|
||||
|
||||
stentry symboltable[MAXBUCKETS];
|
||||
|
||||
stentry **index2stentry;
|
||||
|
||||
void initsymboltable();
|
||||
int symbolindex(char *);
|
||||
char *symbol(int);
|
||||
|
||||
int isvar(int);
|
||||
int staticp(int);
|
||||
void setnonstatic(int);
|
||||
|
||||
/* Symboltable for p(o1,...,on) atoms. */
|
||||
|
||||
int nOfAtoms;
|
||||
|
||||
void initatomtable();
|
||||
|
||||
int atomindex(atom,int *);
|
||||
|
||||
int bvalue(int,int *);
|
||||
|
||||
int printatomi(int i); /* Print an atom and return its length in chars. */
|
||||
|
||||
void renameatomtable(int,int *); /* Rename atoms by using a mapping. */
|
2938
translate2sat.c
Normal file
2938
translate2sat.c
Normal file
File diff suppressed because it is too large
Load Diff
40
translate2sat.h
Normal file
40
translate2sat.h
Normal file
@ -0,0 +1,40 @@
|
||||
|
||||
/* 2012 (C) Jussi Rintanen, jrintanen.jr@gmail.com */
|
||||
|
||||
typedef struct _seq {
|
||||
satinstance sati;
|
||||
int restart;
|
||||
int callsleft;
|
||||
int effort;
|
||||
} seq;
|
||||
|
||||
seq seqs[10000];
|
||||
|
||||
void encoding();
|
||||
|
||||
typedef struct _CEstruct {
|
||||
int var;
|
||||
fma *condition;
|
||||
char disjunctive;
|
||||
struct _CEstruct *next;
|
||||
} CEstruct;
|
||||
|
||||
CEstruct **CEs;
|
||||
|
||||
typedef struct _compactCEstruct {
|
||||
int var;
|
||||
fma *condition;
|
||||
char disjunctive;
|
||||
} compactCEstruct;
|
||||
|
||||
compactCEstruct **cCEs;
|
||||
|
||||
typedef struct _actvar {
|
||||
int *effectlits;
|
||||
int *conditionlits;
|
||||
} actvar;
|
||||
|
||||
int maxactvars;
|
||||
actvar *actvars;
|
||||
|
||||
int actaffects(int,int);
|
364
varvals.c
Normal file
364
varvals.c
Normal file
@ -0,0 +1,364 @@
|
||||
/* 2012 (C) Jussi Rintanen, jrintanen.jr@gmail.com */
|
||||
|
||||
/* Functions to set literals and variables true and false, and to
|
||||
read their values.
|
||||
setlittrue
|
||||
setlitfalse
|
||||
unsetlit
|
||||
setvartrue
|
||||
setvarfalse
|
||||
unsetvar
|
||||
littruep
|
||||
litfalsep
|
||||
litunsetp
|
||||
vartruep
|
||||
varfalsep
|
||||
varunsetp
|
||||
*/
|
||||
|
||||
/*************************************************************************/
|
||||
/************************** one byte per variable ************************/
|
||||
/*************************************************************************/
|
||||
|
||||
#ifdef REPRONE
|
||||
|
||||
#define VARVALUE(v) (sati->variableval[(v)])
|
||||
|
||||
inline int varunset(satinstance sati,int i) { return (VARVALUE(i) = UNASS); }
|
||||
inline int varunsetp(satinstance sati,int i) { return (VARVALUE(i) == UNASS); }
|
||||
|
||||
inline void litsettrue(satinstance sati,int l) { VARVALUE(VAR(l)) = VALUE(l); }
|
||||
inline void litunset(satinstance sati,int l) { VARVALUE(VAR(l)) = UNASS; }
|
||||
inline int litunsetp(satinstance sati,int l) { return varunsetp(sati,VAR(l)); }
|
||||
|
||||
inline int littruep(satinstance sati,int l) { return (VARVALUE(VAR(l)) == VALUE(l)); }
|
||||
inline int litfalsep(satinstance sati,int l) { return (VARVALUE(VAR(l)) == 1-VALUE(l)); }
|
||||
|
||||
/* Value of a state variable. */
|
||||
|
||||
inline int varvalue(satinstance sati,int v) { return VARVALUE(v); }
|
||||
inline int vartruep(satinstance sati,int i) { return (VARVALUE(i) == 1); }
|
||||
inline int varfalsep(satinstance sati,int i) { return (VARVALUE(i) == 0); }
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/************************ 2+2 bits in a 32 bit word **********************/
|
||||
/*************************************************************************/
|
||||
|
||||
#ifdef REPRTWO
|
||||
|
||||
/*
|
||||
Each literal has 2 bits. 1 = TRUE, 2 = FALSE, 0 = UNDEFINED
|
||||
This is quite a bit slower than representation 3. With DriverLog-16
|
||||
REPRTHREE total runtime is 80 per cent of REPRTWO.
|
||||
*/
|
||||
|
||||
inline void setII(satinstance sati,int v,int val) {
|
||||
unsigned int index,slot,word,mask,b;
|
||||
index = v >> 3;
|
||||
slot = (v & 7) * 4;
|
||||
word = sati->variableval[index];
|
||||
mask = 15 << slot;
|
||||
b = val << slot;
|
||||
sati->variableval[index] = (word&(0xffffffff^mask))|b;
|
||||
}
|
||||
|
||||
inline int getII(satinstance sati,int l) {
|
||||
unsigned int index,slot,word;
|
||||
index = l >> 4;
|
||||
slot = (l & 15) * 2;
|
||||
word = sati->variableval[index];
|
||||
return (word >> slot) & 3;
|
||||
}
|
||||
|
||||
inline void litsettrue(satinstance sati,int l) {
|
||||
int val;
|
||||
val = 9-(l&1)*3;
|
||||
setII(sati,l >> 1,val);
|
||||
}
|
||||
|
||||
inline void litsetfalse(satinstance sati,int l) {
|
||||
int val;
|
||||
val = 6+(l&1)*3;
|
||||
setII(sati,l >> 1,val);
|
||||
}
|
||||
|
||||
inline void varsetfalse(satinstance sati,int v) {
|
||||
setII(sati,v,6); // 2 + (1 << 2)
|
||||
}
|
||||
|
||||
inline void varsettrue(satinstance sati,int v) {
|
||||
setII(sati,v,9); // 1 + (2 << 2)
|
||||
}
|
||||
|
||||
inline void litunset(satinstance sati,int l) {
|
||||
setII(sati,l >> 1,0);
|
||||
}
|
||||
|
||||
inline void varunset(satinstance sati,int v) {
|
||||
setII(sati,v,0);
|
||||
}
|
||||
|
||||
inline int littruep(satinstance sati,int l) {
|
||||
return (getII(sati,l) == 1);
|
||||
}
|
||||
|
||||
inline int litfalsep(satinstance sati,int l) {
|
||||
return (getII(sati,l) == 2);
|
||||
}
|
||||
|
||||
inline int litunsetp(satinstance sati,int l) {
|
||||
return (getII(sati,l) == 0);
|
||||
}
|
||||
|
||||
inline int vartruep(satinstance sati,int v) {
|
||||
return (getII(sati,2*v) == 1);
|
||||
}
|
||||
|
||||
inline int varfalsep(satinstance sati,int v) {
|
||||
return (getII(sati,2*v) == 2);
|
||||
}
|
||||
|
||||
inline int varunsetp(satinstance sati,int v) {
|
||||
return (getII(sati,2*v) == 0);
|
||||
}
|
||||
|
||||
inline int varvalue(satinstance sati,int v) {
|
||||
switch(getII(sati,2*v)) {
|
||||
case 1: return 1;
|
||||
case 2: return 0;
|
||||
default: return -1;
|
||||
};
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*************************************************************************/
|
||||
/************** two bytes per variable, one for each literal *************/
|
||||
/*************************************************************************/
|
||||
|
||||
#ifdef REPRTHREE
|
||||
|
||||
inline void litsettrue(satinstance sati,int l) {
|
||||
sati->variableval[l] = 1;
|
||||
sati->variableval[l^1] = 0;
|
||||
}
|
||||
|
||||
inline void litsetfalse(satinstance sati,int l) {
|
||||
sati->variableval[l] = 0;
|
||||
sati->variableval[l^1] = 1;
|
||||
}
|
||||
|
||||
inline void varsetfalse(satinstance sati,int v) {
|
||||
sati->variableval[v*2] = 0;
|
||||
sati->variableval[v*2+1] = 1;
|
||||
}
|
||||
|
||||
inline void varsettrue(satinstance sati,int v) {
|
||||
sati->variableval[v*2] = 1;
|
||||
sati->variableval[v*2+1] = 0;
|
||||
}
|
||||
|
||||
inline void litunset(satinstance sati,int l) {
|
||||
// printf("UNSET: "); printTlit(sati,l); printf("\n");
|
||||
sati->variableval[l] = -1;
|
||||
sati->variableval[l^1] = -1;
|
||||
}
|
||||
|
||||
inline void varunset(satinstance sati,int v) {
|
||||
// printf("UNSET: "); printTlit(sati,PLIT(v)); printf("\n");
|
||||
sati->variableval[v*2] = -1;
|
||||
sati->variableval[v*2+1] = -1;
|
||||
}
|
||||
|
||||
inline int littruep(satinstance sati,int l) {
|
||||
return (sati->variableval[l] == 1);
|
||||
}
|
||||
|
||||
inline int litfalsep(satinstance sati,int l) {
|
||||
return (sati->variableval[l] == 0);
|
||||
}
|
||||
|
||||
inline int litunsetp(satinstance sati,int l) {
|
||||
return (sati->variableval[l] == -1);
|
||||
}
|
||||
|
||||
inline int vartruep(satinstance sati,int v) {
|
||||
return (sati->variableval[2*v] == 1);
|
||||
}
|
||||
|
||||
inline int varfalsep(satinstance sati,int v) {
|
||||
return (sati->variableval[2*v] == 0);
|
||||
}
|
||||
|
||||
inline int varunsetp(satinstance sati,int v) {
|
||||
return (sati->variableval[2*v] == -1);
|
||||
}
|
||||
|
||||
inline int varvalue(satinstance sati,int v) {
|
||||
return (sati->variableval[2*v]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef REPRFOUR
|
||||
|
||||
/*
|
||||
Each literal has 1 bit, indicating that it is true. If l and -l are both
|
||||
not true, then the literal is unassigned.
|
||||
*/
|
||||
|
||||
/* Set bit true. */
|
||||
|
||||
inline void setI(satinstance sati,int l) {
|
||||
unsigned int index,slot,word;
|
||||
index = l >> 5;
|
||||
slot = l & 31;
|
||||
word = sati->variableval[index];
|
||||
sati->variableval[index] = word|(1 << slot);
|
||||
}
|
||||
|
||||
/* Zero two bits. */
|
||||
|
||||
inline void unsetII(satinstance sati,int l) {
|
||||
unsigned int index,slot,word,mask,l0;
|
||||
l0 = l&0xfffffffe;
|
||||
index = l0 >> 5;
|
||||
slot = l0 & 31;
|
||||
word = sati->variableval[index];
|
||||
mask = 3 << slot;
|
||||
sati->variableval[index] = word&(0xffffffff^mask);
|
||||
}
|
||||
|
||||
inline int getI(satinstance sati,int l) {
|
||||
unsigned int index,slot,word;
|
||||
index = l >> 5;
|
||||
slot = l & 31;
|
||||
word = sati->variableval[index];
|
||||
return word&(1 << slot);
|
||||
}
|
||||
|
||||
inline int getII(satinstance sati,int l) {
|
||||
unsigned int index,slot,word;
|
||||
index = l >> 5;
|
||||
slot = l & 31;
|
||||
word = sati->variableval[index];
|
||||
return (word&(3 << slot)) >> slot;
|
||||
}
|
||||
|
||||
/* If not set, set true and return 1. */
|
||||
|
||||
inline int litunset2true(satinstance sati,int l) {
|
||||
unsigned int index,slot,word,mask,l0,b;
|
||||
l0 = l&0xfffffffe;
|
||||
index = l0 >> 5;
|
||||
slot = l0 & 31;
|
||||
word = sati->variableval[index];
|
||||
mask = 3 << slot;
|
||||
if(word & mask) return 0;
|
||||
b = (l&1)+1;
|
||||
// b = 1 << (l&1)+1;
|
||||
sati->variableval[index] = word|(b << slot);
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline void litsettrue(satinstance sati,int l) {
|
||||
setI(sati,l);
|
||||
}
|
||||
|
||||
inline void litsetfalse(satinstance sati,int l) {
|
||||
setI(sati,l^1);
|
||||
}
|
||||
|
||||
inline void varsetfalse(satinstance sati,int v) {
|
||||
setI(sati,2*v+1);
|
||||
}
|
||||
|
||||
inline void varsettrue(satinstance sati,int v) {
|
||||
setI(sati,2*v);
|
||||
}
|
||||
|
||||
inline void litunset(satinstance sati,int l) {
|
||||
unsetII(sati,l);
|
||||
}
|
||||
|
||||
inline void varunset(satinstance sati,int v) {
|
||||
unsetII(sati,2*v);
|
||||
}
|
||||
|
||||
inline int littruep(satinstance sati,int l) {
|
||||
return getI(sati,l);
|
||||
}
|
||||
|
||||
inline int litfalsep(satinstance sati,int l) {
|
||||
return getI(sati,l^1);
|
||||
}
|
||||
|
||||
inline int litunsetp(satinstance sati,int l) {
|
||||
return (getII(sati,l&0xfffffffe) == 0);
|
||||
}
|
||||
|
||||
inline int vartruep(satinstance sati,int v) {
|
||||
return getI(sati,2*v);
|
||||
}
|
||||
|
||||
inline int varfalsep(satinstance sati,int v) {
|
||||
return getI(sati,2*v+1);
|
||||
}
|
||||
|
||||
inline int varunsetp(satinstance sati,int v) {
|
||||
return (getII(sati,2*v) == 0);
|
||||
}
|
||||
|
||||
inline int varvalue(satinstance sati,int v) {
|
||||
switch(getII(sati,2*v)) {
|
||||
case 0: return -1;
|
||||
case 1: return 1;
|
||||
default: return 0;
|
||||
};
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
inline int tvarvalue(satinstance sati,int v,int t) { return varvalue(sati,TVAR(v,t)); }
|
||||
inline int tvartime(satinstance sati,int vt) { return vt/sati->nOfVarsPerTime; }
|
||||
inline int tvarvar(satinstance sati,int vt) { return vt%sati->nOfVarsPerTime; }
|
||||
|
||||
inline int untimevar(satinstance sati,int v) { return (v%(sati->nOfVarsPerTime)); }
|
||||
inline int litwithtime(satinstance sati,int l,int t) {
|
||||
// return (((l >> 1) + sati->nOfVarsPerTime * t) << 1) | (l&1);
|
||||
return l + 2 * sati->nOfVarsPerTime * t;
|
||||
}
|
||||
inline int varwithtime(satinstance sati,int v,int t) {
|
||||
return v + sati->nOfVarsPerTime * t;
|
||||
}
|
||||
|
||||
|
||||
inline int tvartruep(satinstance sati,int v,int t) {
|
||||
return vartruep(sati,varwithtime(sati,v,t));
|
||||
}
|
||||
|
||||
inline int tvarfalsep(satinstance sati,int v,int t) {
|
||||
return varfalsep(sati,varwithtime(sati,v,t));
|
||||
}
|
||||
|
||||
inline int tvarunsetp(satinstance sati,int v,int t) {
|
||||
return varunsetp(sati,varwithtime(sati,v,t));
|
||||
}
|
||||
|
||||
|
||||
inline int tlittruep(satinstance sati,int l,int t) {
|
||||
return littruep(sati,litwithtime(sati,l,t));
|
||||
}
|
||||
|
||||
inline int tlitfalsep(satinstance sati,int l,int t) {
|
||||
return litfalsep(sati,litwithtime(sati,l,t));
|
||||
}
|
||||
|
||||
inline int tlitunsetp(satinstance sati,int l,int t) {
|
||||
return litunsetp(sati,litwithtime(sati,l,t));
|
||||
}
|
Loading…
Reference in New Issue
Block a user