Initial commit with Madagascar 2016-01-22

This commit is contained in:
Patrick Lühne 2018-01-25 16:50:51 +01:00 committed by Patrick Lühne
commit 21571c20a1
Signed by: patrick
GPG Key ID: 05F3611E97A70ABF
45 changed files with 15026 additions and 0 deletions

109
Cground.c Normal file
View 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
View 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
View 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
View 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
View 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();

1
build Executable file
View File

@ -0,0 +1 @@
make

491
clausedb.c Normal file
View 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
View 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

File diff suppressed because it is too large Load Diff

12
clausesets.h Normal file
View 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
View 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
View File

@ -0,0 +1,4 @@
/* 2012 (C) Jussi Rintanen */
void cleanupoperators();

4
dimacs.h Normal file
View File

@ -0,0 +1,4 @@
/* 2012 (C) Jussi Rintanen */
void dimacsheader(FILE *,int,int);

157
dimacsinput.c Normal file
View 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
View File

@ -0,0 +1,4 @@
/* 2010 (C) Jussi Rintanen */
satinstance DIMACSinput();

812
ground.c Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View File

@ -0,0 +1,7 @@
/* 2012 (C) Jussi Rintanen */
int *onelits;
intset *twolits;
void computeinvariants();

335
learn2.c Normal file
View 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
View 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
View 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",&paramA)) {
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",&paramB)) {
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",&paramC)) {
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",&paramM)) {
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
View 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
View 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

File diff suppressed because it is too large Load Diff

167
operators.h Normal file
View 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
View 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
View 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
View 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;
}

1
plan Executable file
View File

@ -0,0 +1 @@
./nplan $1 $2 -o $3 -Q

291
printplan.c Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

40
translate2sat.h Normal file
View 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
View 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));
}

1
zPOSTF Normal file
View File

@ -0,0 +1 @@
");

1
zPREF Normal file
View File

@ -0,0 +1 @@
printf("Madagascar 0.99999