C


Ubuntu: How to compile STAN SPG Planning System (http://planning.cis.strath.ac.uk/STAN/) on Ubuntu 11.10

Recently we tried to compile the STAN SPG Planning System (http://planning.cis.strath.ac.uk/STAN/) under Ubuntu 11.10  Oneiric Ocelot which ended up in a failure.

After reviewing the source code of version 3 (http://planning.cis.strath.ac.uk/code/) we found out that there were many changes needed to be done that had to do with the age of the code itself. We believe that with an OS from1999 and the repsective g++ libraries there should be no problem compiling this application but who has one anyway ? (From the README file: “The code has been built and tested using Linux and UNIX (SunOS) with the g++ compiler.” )

Solution:

We realized that most of the errors are pretty much the same ones and had to do with C++ syntax. Following a synopsis of the changes we did:

    • Replaced
      #include <stream.h>

      with

      #include <iostream>
      using namespace std;

      Note on this, be sure to put using namespace std; after the rest of the includes to avoid conflicts and other issues that might arise.

    • Replaced
      #include <stream.h>

      with

      #include <fstream>
    • Replaced
      #include <new.h>

      with

      #include <new>
    • Added
      #include <cstring>
      #include <stdlib.h>

      wherever there was a call for string manipulation like (strcmp(),strlen(),strcpy(),..) or whenever there were commands like exit().

    • Replaced array assignments like:
      exvec = pl.exvec;

      to

      for(int i = 0;i<EXVECSIZE;i++)  {
        exvec[i] = pl.exvec[i];
      };

      The ranges of these arrays we were able to find them from the respective .h files.

    • In the makefile, we changed:
      pddl.yacc.tab.c: alldefs.h pddl.yacc lex.yy.c
          bison pddl.yacc

      to

      pddl.yacc.tab.c: alldefs.h pddl.yacc lex.yy.c
          bison pddl.yacc -o pddl.yacc.tab.c

      Or else the make will fail as it will not find the file pddl.yacc.tab.c.

In the next section you will find all changes we did to the files extensively (Hopefully we did not forget any or mess them up). The format is as follows (the changes do not necessarily imply that all changes should happen at the same place in file):

in <FILE>
line that was changed/deleted
line that was changed/deleted
-
line that was added
line that was added
line that was added
  1. in Makefile
    pddl.yacc.tab.c: alldefs.h pddl.yacc lex.yy.c
    bison pddl.yacc

    pddl.yacc.tab.c: alldefs.h pddl.yacc lex.yy.c
    bison pddl.yacc -o pddl.yacc.tab.c
  2. in BasicTim.h
    #include <stream.h>

    #include <iostream>
    using namespace std; // make sure it goes right after the includes (I believe it affects stdio.h)
  3. in SymTab.cc
    #include <stream.h>

    #include <iostream>
    #include <cstring>
    #include <stdlib.h>
    using namespace std;
  4. in BasicTim.cc
    #include <fstream.h>

    #include <fstream>
  5. in TimInterface.cc
    #include <fstream.h>

    #include <fstream>
  6. in globals.h
    #include <stream.h>
    #include <fstream.h>

    #include <fstream>
    #include <iostream>
    using namespace std;
  7. in stan.h
    #include <stream.h>

    #include <iostream>
    using namespace std;
  8. in facts.h
    #include “stream.h”

    #include <iostream>
    #include <cstring>
    using namespace std;
  9. in facts.cc
    #include <stream.h>

    #include <iostream>
    using namespace std;
  10. in facts.cc
    exvec = pl.exvec;

    for(int i = 0;i<EXVECSIZE;i++) {
    exvec[i] = pl.exvec[i];
    };
  11. in facts.cc
    domination = pl.domination;

    for(int i = 0;i<EXVECSIZE;i++)  {
    domination[i] = pl.domination[i];
    };
  12. in actions.cc
    exvec = pl.exvec;

    for(int i = 0;i<EXVECSIZE;i++)  {
    exvec[i] = pl.exvec[i];
    };
  13. in instantiation.cc
    #include <stream.h>

    #include <iostream>
    using namespace std;
  14. in candidates.h
    #include <stream.h>

    #include <iostream>
    using namespace std;
  15. in main.cc
    #include <stream.h>
    #include <fstream.h>
    #include <new.h>

    #include <iostream>
    #include <fstream>
    #include <new>
    #include <stdlib.h>
    using namespace std;

Soon we will add the modified version of the source code online that should be able to compile by just issuing make stan.


C/C++: Capture stdout from a system() command

	FILE *results;
	int queen;
	if (!(results = popen("./precosat -f nqueens.cnf | tail -n +2 | head -n -1 | tr -d v | tr ' ' '\n' | grep -v '^$' | grep ^[0-9]", "r"))) {
		cout << "Unable to Execute Precosat" << endl << "./precosat -f nqueens.cnf | tail -n +2 | head -n -1 | tr -d v | tr ' ' '\n' | grep -v '^$' | grep ^[0-9]" << endl;
		exit(1);
	}
	for (i = 0; i < queens; i++) {
		fscanf(results,"%d",&queen);
		cout << "Queen #" << i+1 << " goes to [" << ((queen%queens)?(queen%queens):queens) << "]" << endl;
	}
	pclose(results);

Above, you will find an example that was used to extract data from the PrecoSAT SAT Solver in order to solve the N-Queens problem. It returns all positive variables, one per line.

You can see that after the call to popen, it creates a pointer to a file stream that can be used as a regular file to read the data from the called process.