Advertisement
logicmoo

Untitled

Aug 15th, 2018
577
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.82 KB | None | 0 0
  1. // #define LISP90 1
  2. #define DEBUGGING 1
  3.  
  4. #ifdef LISP90
  5. int test_program_append();
  6. #include "lisp90.cpp"
  7. #else
  8. #define nonvar char*
  9. #define read_atom(s) s
  10. // #define to_string(s) s
  11. #endif
  12.  
  13. #define C_TEXT( text ) ((char*)std::string( text ).c_str())
  14. #undef C_TEXT
  15. #define C_TEXT( text ) ((char*)text)
  16.  
  17. #define MKATOM(TEXT) new Atom(C_TEXT(TEXT))
  18. #define FACT(TEXT) new Clause(TEXT)
  19. #define RULE(HEAD,BODY...) new Clause(HEAD,BODY)
  20.  
  21. /*Psuedovars for source translation */
  22. #define PSUEDOVAR(NAME)  Var* V(NAME) = new Var()
  23. #define V(NAME) VAR_ ## NAME
  24. #define TERMS Structure*
  25.  
  26.  
  27. /* Create a Callable Compound*/
  28. #define CC(TEXT...) new Structure(TEXT)
  29. /* Create a List*/
  30. #define LL(TEXT...) CC(ATOM_dot,TEXT)
  31.  
  32. #ifdef DEBUGGING
  33. //#define DEBUG(mask,CPP) if ((mask & debugflags)!=0) CPP
  34. #define DEBUG(mask,CPP) CPP
  35. #else
  36. #define DEBUG(mask,CPP)
  37. #endif
  38.  
  39. #include <iostream>
  40. using namespace std;
  41. #include <string.h>
  42.  
  43. void indent(int n)
  44. {
  45.   for(int i = 0; i<n; i++) cout << "    ";
  46. }
  47.  
  48. class Trail; class Structure; class Var; class Prog1Pred;
  49.  
  50. class TermVarMapping
  51. {
  52. private:
  53.   Var* *varvar;
  54.   const char* *vartext;
  55.   int size;
  56. public:
  57.   TermVarMapping(Var* vv[], const char* vt[], int vs)
  58.   :varvar(vv), vartext(vt), size(vs)
  59.   {
  60.   }
  61.   void showanswer()
  62.   {
  63.     if(size == 0) cout << "yes\n";
  64.     else
  65.     {
  66.       for(int i = 0; i < size; i++)
  67.         cout << vartext[i] << " = " << varvar[i] << "\n";
  68.     }
  69.   }
  70. };
  71.  
  72. class Term
  73. {
  74. public:
  75.   virtual bool unify(Trail* ,Term* ) = 0;
  76.   virtual bool unify2(Trail* , TERMS ) = 0;
  77.   virtual Term* copy(Trail* ) = 0;
  78.   virtual void reset() = 0;
  79.   void debug() { cout<<this; }
  80.   virtual ostream& operator<<(ostream& str) = 0;
  81. };
  82.  
  83. class Trail
  84. {
  85. private:
  86.   Term* tcar;
  87.   Trail* tcdr;
  88.   Trail* sofar;
  89.   Trail(Term* h, Trail* t) : tcar(h), tcdr(t){}
  90. public:
  91.   Trail() : tcar(NULL), tcdr(NULL) {}
  92.   Trail* Note() { return(sofar);}
  93.   void Push(Term* x) {sofar = new Trail(x, sofar);}
  94.   void Undo(Trail* whereto)
  95.   {
  96.     for(; sofar != whereto; sofar = sofar->tcdr)
  97.       sofar->tcar->reset();
  98.   }
  99. };
  100.  
  101.  
  102. class Atom
  103. { nonvar atomname;
  104. public: Atom(char* s) :
  105.     #ifdef LISP90
  106.        atomname(read_atom(s)){}
  107.     #else
  108.        atomname(s){}
  109.     #endif
  110.  
  111.   const char* c_str()          
  112.   {
  113.     #ifdef LISP90
  114.        return to_string(atomname).c_str();
  115.     #else
  116.        return atomname;
  117.     #endif
  118.   }
  119.  
  120.   ostream& operator<<(ostream& str)
  121.   { return str <<  "atom(" << c_str() << ")"; }
  122.  
  123.   bool eqatom(Atom* t)
  124.   { return(strcmp(c_str(),t->c_str()) == 0);
  125.   }
  126. };
  127.  
  128.  
  129. Atom* ATOM_nil = MKATOM("[]");
  130. Atom* ATOM_dot = MKATOM(".");
  131.  
  132. class Structure : public Term
  133. { int arity;
  134.   Atom* fsym;
  135.   Term** args;
  136. public:
  137.   Structure(const char* f): fsym(MKATOM(f)), arity(0), args(NULL){}
  138.   Structure(Atom* f): fsym(f), arity(0), args(NULL){}
  139.   Structure(Atom* f, Term* a1): fsym(f), arity(1), args(new Term*[1]){args[0]=a1;};
  140.   Structure(Atom* f, Term* a1, Term* a2): fsym(f), arity(2), args(new Term*[2]){args[0]=a1, args[1]=a2;};
  141.   Structure(Atom* f, Term* a1, Term* a2, Term* a3): fsym(f), arity(3), args(new Term*[3]){args[0]=a1, args[1]=a2, args[2]=a3;}
  142.  
  143.   ostream& operator<<(ostream& str)
  144.   {
  145.     if(fsym==ATOM_dot)
  146.     {
  147.       str <<"[";
  148.       for(int i = 0; i<arity;)
  149.       {
  150.         str << args[i++];
  151.         if(args[i] == NULL) continue;
  152.         if(i < arity) str << "|";
  153.       }
  154.       return str <<"]";
  155.     }
  156.     str << fsym;
  157.     if(arity>0)
  158.     {
  159.       str <<"(";      
  160.       for(int i = 0; i<arity;)
  161.       {
  162.         str << args[i];
  163.         if(++i < arity) str << ",";
  164.       }
  165.       str <<")";
  166.     }
  167.     return str;
  168.   }
  169.   bool unify(Trail* mach,Term* t)
  170.   {
  171.     return(t->unify2(mach,this));
  172.   }
  173.   Term* copy(Trail* mach)
  174.   {
  175.     return(copyNonvar(mach));
  176.   }
  177.   TERMS copyNonvar(Trail* mach)
  178.   {
  179.     return(CC(mach,this));
  180.   }
  181.   virtual void reset(){}
  182. private:
  183.   Structure(Trail* mach, TERMS p)
  184.   : fsym(p->fsym), arity(p->arity),
  185.   args(p->arity==0 ? NULL : new Term*[p->arity])
  186.   {
  187.     for(int i=0; i<arity; i++) args[i] = p->args[i]->copy(mach);
  188.   }
  189.  
  190.   bool unify2(Trail* mach, TERMS t)
  191.   {
  192.     if(!(fsym->eqatom(t->fsym) && arity == t->arity))
  193.       return(false);
  194.     for(int i = 0; i<arity; i++)
  195.       if(!args[i]->unify(mach,t->args[i])) return(false);
  196.     return(true);
  197.   }
  198. };
  199.  
  200. class Var : public Term
  201. {
  202. private:
  203.   Term* instance;
  204.   int varno;
  205.   static int timestamp;
  206. public:
  207.   Var() : instance(this), varno(++timestamp) {}
  208.   ostream& operator<<(ostream& str)
  209.   { if(instance!=this) return str << instance; else return str <<"_"<<varno;
  210.   }
  211.   virtual void reset() {instance = this;}
  212. private:
  213.   bool unify2(Trail* mach,TERMS t)
  214.   {
  215.     return(this->unify(mach,t));
  216.   }
  217.   bool unify(Trail* mach, Term* t)
  218.   {
  219.     if(instance!=this) return(instance->unify(mach,t));
  220.     mach->Push(this); instance = t; return(true);
  221.   }
  222.  
  223.   Term* copy(Trail* mach)
  224.   {
  225.     if(instance==this)
  226.     {
  227.       mach->Push(this); instance = new Var();
  228.     }
  229.     return(instance);
  230.   }
  231. };
  232.  
  233. int Var::timestamp = 0;
  234.  
  235.  
  236. class Goal
  237. {
  238. private:
  239.   TERMS car;
  240.   Goal* cdr;
  241.   Trail* mach;
  242.  
  243. public:
  244.   Goal(TERMS h ) : car(h), cdr(NULL) {mach = new Trail();}
  245.   Goal(TERMS h, Goal* t) : car(h), cdr(t) {mach = new Trail();}
  246.  
  247.   Goal* copy(Trail* mach) {
  248.     return(new Goal(car->copyNonvar(mach),
  249.                     cdr==NULL ? NULL : cdr->copy(mach)));
  250.   }
  251.   Goal* append(Goal* l)
  252.   { return(new Goal(car,cdr==NULL ? NULL : cdr->append(l))); }
  253.  
  254.   ostream& operator<<(ostream& str)
  255.   {  str << "GOAL: " << car;
  256.      if (cdr != NULL) str << ", " << cdr;
  257.      return str;
  258.    }
  259.  
  260.   Prog1Pred* solve(Prog1Pred* p, int level, TermVarMapping* map);
  261. };
  262.  
  263. class Clause
  264. {
  265. public:
  266.   TERMS head;
  267.   Goal* body;
  268.   Clause(TERMS h, Goal* t) : head(h), body(t) {}
  269.   Clause(TERMS h, TERMS t) : head(h), body(new Goal(t)) {}
  270.   Clause(TERMS h) : head(h), body(NULL) {}
  271.  
  272.   Clause* copy(Trail* mach)
  273.   { return(RULE(head->copyNonvar(mach),
  274.                       body==NULL ? NULL : body->copy(mach)));
  275.   }
  276.   ostream& operator<<(ostream& str)
  277.   { str << head << " :- ";
  278.     if(body==NULL) str<<"true"; else str<<body;
  279.     return str;
  280.   }
  281.  
  282.   Clause* append(TERMS l)
  283.   { if(body==NULL) {body = new Goal(l);}
  284.     else {
  285.        body = body->append(new Goal(l));
  286.     }
  287.     return this;
  288.   }
  289.  
  290. };
  291.  
  292. class Prog1Pred
  293. {
  294. public:
  295.   Clause* pcar;
  296.   Prog1Pred* pcdr;
  297.   Prog1Pred(Clause* h) : pcar(h), pcdr(NULL){}
  298.   Prog1Pred(Clause* h, Prog1Pred* t) : pcar(h), pcdr(t){}
  299.   Prog1Pred(Clause* h, Clause* t) : pcar(h), pcdr(new Prog1Pred(t)){}
  300.   Prog1Pred(Clause* h, Clause* h2, Clause* t) : pcar(h), pcdr(new Prog1Pred(h2, t)){}
  301.  
  302.   /* returns the newly appended Prog1Pred*/
  303.   Prog1Pred* append(Clause* l)
  304.   { if(pcdr==NULL) {return pcdr = new Prog1Pred(l);}
  305.     else {
  306.        return pcdr->append(l);
  307.     }    
  308.   }
  309.  
  310.   /* returns itself*/
  311.   Prog1Pred* prepend(Clause* h)
  312.   {
  313.     pcdr = new Prog1Pred(pcar, pcdr);
  314.     pcar = h;
  315.     return this;
  316.   }
  317. };
  318.  
  319.  
  320. TERMS NIL = CC(ATOM_nil);
  321.  
  322. TERMS CUT = CC(MKATOM("!"));
  323. /* returns a new Goal if coroutining or null if cutted */
  324. Prog1Pred* Goal::solve(Prog1Pred* p, int level, TermVarMapping* map)
  325. {
  326.   if(mach==NULL) mach = new Trail();
  327.  
  328.   Prog1Pred* retQ = p;
  329.  
  330.   DEBUG(SOLVE,{ indent(level); cout << "solve@"  << level << ": " << this << "\n";});
  331.  
  332.   for(Prog1Pred* q = p; q != NULL; q = q->pcdr)
  333.   {
  334.     Trail* t = mach->Note();
  335.     Clause* next = q->pcar;
  336.     /*
  337.     if(next ==CUT)
  338.     {
  339.       //cutTo =
  340.       // should succeed
  341.       DEBUG(SOLVE,{ indent(level); str << "  cut: " <<  q << "\n";});
  342.       return retQ;
  343.     }
  344.     */
  345.  
  346.     retQ = q;
  347.  
  348.     Clause* c = next->copy(mach);
  349.     mach->Undo(t);
  350.     DEBUG(SOLVE,{ indent(level); cout << "  try: " <<  c << "\n";});
  351.     if(car->unify(mach,c->head))
  352.     {
  353.       Goal* gdash = c->body==NULL ? cdr : c->body->append(cdr);
  354.       if(gdash == NULL) map->showanswer();
  355.       else gdash->solve(p, level+1, map);
  356.     }
  357.     else
  358.     {
  359.       DEBUG(SOLVE,{
  360.           indent(level); cout << "  nomatch.\n";});
  361.       //break;
  362.     }
  363.     mach->Undo(t);
  364.   }
  365. }
  366.  
  367.  
  368.  
  369. int test_program_append()
  370. {
  371. /*Psuedovars for source translation */
  372. PSUEDOVAR(X);
  373. PSUEDOVAR(L);
  374. PSUEDOVAR(M);
  375. PSUEDOVAR(N);
  376. PSUEDOVAR(I);
  377. PSUEDOVAR(J);
  378.  
  379.  
  380.   Atom* APPEND3 = MKATOM("append_3");
  381.  
  382.  
  383.  
  384.  
  385.   /* append_3([],X,X). */
  386.   Clause* c1 = FACT(CC(APPEND3, NIL, VAR_X, VAR_X));
  387.   /*  append([X|LL],M,[X|N]):- append(LL,M,N). */
  388.   Clause* c2 = RULE(CC(APPEND3, LL(VAR_X, VAR_L),VAR_M, LL(VAR_X,VAR_N)), CC(APPEND3, VAR_L, VAR_M, VAR_N));
  389.  
  390.  
  391.   /*
  392.      Test normally:    
  393.      
  394.       append_3([],X,X).
  395.       append([X|LL],M,[X|N]):- append(LL,M,N).
  396.   */
  397.   Prog1Pred* test_program_normally = new Prog1Pred(c1, c2);
  398.  
  399.  
  400.   /*
  401.     Test reversed:
  402.  
  403.       append([X|LL],M,[X|N]):- append(LL,M,N).
  404.       append_3([],X,X).
  405.   */
  406.   Prog1Pred* test_program_reversed = new Prog1Pred(c2, c1);
  407.  
  408.  
  409.   /*
  410.      Test Cat:    
  411.  
  412.       append_3([],X,X):- !.
  413.       append([X|LL],M,[X|N]):- append(LL,M,N).
  414.   */
  415.   Clause* c3 = c1->copy(new Trail());
  416.   c3->append(CUT);
  417.  
  418.   Prog1Pred* test_program_cut = new Prog1Pred(c3, c2);
  419.  
  420.  
  421.  
  422.   Var* varvar[] = {VAR_I,VAR_J};
  423.   const char* varname[] = {"I", "J"};
  424.   TermVarMapping* var_name_map = new TermVarMapping(varvar, varname, 2);
  425.  
  426.   /*
  427.      ?- append_3(I,J,[1,2,3]).
  428.   */
  429.   Goal* g1 = new Goal(CC(APPEND3, VAR_I, VAR_J, LL( CC("1"),LL( CC("2"),LL( CC("3"), NIL)))));
  430.  
  431.   cout << "=======Append with normal clause order:\n";
  432.   g1->solve(test_program_normally, 0, var_name_map);
  433.  
  434.   cout << "\n=======Append with reversed normal clause order:\n";
  435.   g1->solve(test_program_reversed, 0, var_name_map);
  436.  
  437.   cout << "\n=======Append with a cut:\n";
  438.   g1->solve(test_program_cut, 0, var_name_map);
  439.  
  440.   return(0);
  441. }
  442.  
  443.  
  444. #ifndef LISP90
  445. int main(int argc, char* argv[]) {
  446.    test_program_append();
  447. }
  448. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement