Advertisement
logicmoo

Untitled

Aug 19th, 2018
729
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 17.92 KB | None | 0 0
  1. // ConsoleApplication2.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. #include "stdafx.h"
  5.  
  6. /* prolog.c: a simple Prolog interpreter written in C++,               */
  7. /*           including an example test run as main().                  */
  8. /* Copyright (c) Alan Mycroft, University of Cambridge, 2000.          */
  9. /*
  10.  
  11.                 original from https://www.cl.cam.ac.uk/~am21/research/funnel/prolog.c
  12.  
  13.                 Dmiles made trhe trail non static
  14.  
  15. */
  16.  
  17. // #define LISP90 1
  18. #define DEBUGGING 1
  19. #define USE_CUT 1
  20.  
  21. void myBreak() {
  22.     ;;;
  23. }
  24.  
  25.  
  26. int test_program_append(bool interactive);
  27.  
  28. #ifdef LISP90
  29. #include "lisp90.cpp"
  30. #else
  31. // #define read_atom(s) s
  32. // #define to_string(s) s
  33. #endif
  34.  
  35. #define C_TEXT( text ) ((char*)std::string( text ).c_str())
  36. #undef C_TEXT
  37. #define C_TEXT( text ) ((char*)text)
  38.  
  39. #define MKATOM(TEXT) AtomTable::GetAtom(TEXT)
  40. #define FACT(TEXT) new Clause(TEXT)
  41. #define RULE(HEAD,...) new Clause(HEAD,__VA_ARGS__)
  42.  
  43. /*Psuedovars for source translation */
  44. #define PSUEDOVAR(NAME)  Var* V(NAME) = new Var()
  45. #define V(NAME) VAR_ ## NAME
  46.  
  47.  
  48. /* Create a Callable Compound*/
  49. #define CC(...) new Fun(__VA_ARGS__)
  50. /* Create a List*/
  51. #define LL(...) CC(ATOM_dot,__VA_ARGS__)
  52.  
  53. #ifdef DEBUGGING
  54. //#define DEBUG(mask,CPP) if ((mask & debugflags)!=0) CPP
  55. #define DEBUG(mask,CPP) CPP
  56. #else
  57. #define DEBUG(mask,CPP)
  58. #endif
  59.  
  60. #include <iostream>
  61. #include <sstream>
  62. using namespace std;
  63. #include <string.h>
  64. #include <string>
  65. #include <map>
  66. #include <unordered_map>
  67. #include <vector>
  68.  
  69. void indent(ostream& str, int n) {
  70.     for(int i = 0; i < n; i++) str << "    ";
  71. }
  72. void indent(int n) {
  73.     indent(cout, n);
  74. }
  75.  
  76. class Prolog; class Term;
  77.  
  78. class Prog1Pred;
  79. #define HashMap std::unordered_map<std::string, Prog1Pred*>
  80.  
  81. class PredTable
  82. {
  83. public:
  84.     std::vector<HashMap> tables;
  85.  
  86.     PredTable()
  87.     {
  88.         tables = std::vector<HashMap>(33);
  89.     }
  90.  
  91.  
  92.     void InsertNameArity(const std::string& N, const int& A, Prog1Pred* Adr)
  93.     {
  94.         HashMap T = tables[A];
  95.         if(T.empty())
  96.         {
  97.             tables[A] = T = HashMap();
  98.         }
  99.         T.emplace(N, Adr);
  100.     }
  101.  
  102.     Prog1Pred* IsInPredTable(const std::string& N, const int& A)
  103.     {
  104.         if(tables[A].empty())
  105.         {
  106.             return(nullptr);
  107.         }
  108.         return(static_cast<Prog1Pred*>(tables[A][N]));
  109.     }
  110. };
  111.  
  112. class Prog1Pred;
  113.  
  114. class Sym {
  115.  
  116. public:
  117.  
  118.     virtual Sym* copyAtom(Prolog* m) = 0;
  119.     virtual const char* typeName() = 0;
  120.     virtual ostream& operator<<(ostream& str) {
  121.         print(str); return(str);
  122.     }
  123.     // at least one of these next two methods need to be overriden
  124.     virtual void print(ostream& str) {
  125.         str << c_str();
  126.     }
  127.     virtual const char* c_str()
  128.     {
  129.         std::ostringstream stream;
  130.         print(stream);
  131.         std::string str =  stream.str();
  132.         return(str.c_str());
  133.     }
  134.  
  135.     // this is horrid and should be overridden
  136.     virtual bool eqatom(Sym* t) {
  137.         if(t==this) return(true);
  138.         return(strcmp(c_str(), t->c_str()) == 0);
  139.     }
  140.  
  141. };
  142.  
  143.  
  144. class SymAtom : public Sym {
  145.     std::string atomname;
  146.  
  147.     const char* MYTYPE = "SymAtom";
  148. public:
  149.     virtual const char* typeName() { return(MYTYPE);}
  150.     SymAtom(const char* s) :  atomname(s) {}
  151.  
  152.     virtual void print(ostream& str) {
  153.         // str <<  "'" ;
  154.         str << atomname;
  155.         // str << "'";
  156.     }
  157.  
  158.     virtual Sym* copyAtom(Prolog* m) {
  159.         return(this);
  160.     }
  161.  
  162.     virtual const char* c_str() {
  163.         return(atomname.c_str());
  164.     }
  165.  
  166.     virtual bool eqatom(Sym* t) {
  167.             if(typeName() != MYTYPE) return(false);
  168.         return(strcmp(c_str(), t->c_str()) == 0);
  169.     }
  170.  
  171.     // Might store preds here?
  172.     // std::vector<Prog1Pred*> preds = std::vector<Prog1Pred*>(33);
  173.  
  174. };
  175.  
  176. #define InternalSymHashMap std::unordered_map<std::string,Sym*>
  177.  
  178. class SymMap
  179. {
  180. public:
  181.     InternalSymHashMap symtable = InternalSymHashMap();
  182.     Sym* GetData(const std::string N)
  183.     {
  184.         Sym* A = symtable[N];
  185.         return(A);
  186.     }
  187.     void PutData(const std::string N, Sym* data)
  188.     {
  189.         symtable[N] = data;
  190.     }
  191.     virtual ostream& operator<<(ostream& str) {
  192.         str << &symtable;
  193.       return(str);
  194.     }
  195.  
  196. };
  197.  
  198.  
  199. class AtomTable
  200. {
  201. public:
  202.     static SymMap* symtable;
  203.  
  204.     static Sym* GetAtom(const std::string N)
  205.     {
  206.         Sym* A = symtable->GetData(N);
  207.         if(A == NULL) {
  208.              A = new SymAtom(N.c_str());
  209.              symtable->PutData(N,A);
  210.         }
  211.         return(A);
  212.     }
  213. };
  214. SymMap* AtomTable::symtable = new SymMap();
  215.  
  216.  
  217. class Fun;
  218. class Term {
  219. public:
  220.     void print() {
  221.         print(cout);
  222.     }
  223.     virtual ostream& operator<<(ostream& str) {
  224.         print(str); return(str);
  225.     }
  226.     virtual void print(ostream& str) = 0;
  227.     virtual bool unifyTerm(Prolog*, Term*) = 0;
  228.     virtual bool unifyStructure(Prolog*, Fun*) = 0;
  229.     virtual Term* copyTerm(bool fresh, Prolog*) = 0;
  230.     virtual void reset(Prolog*) = 0;
  231. };
  232.  
  233.  
  234. Sym* ATOM_nil = MKATOM("[]");
  235. Sym* ATOM_dot = MKATOM(".");
  236.  
  237. class Fun : public Term {
  238.     Sym* fsym; int arity; Term** Arguments;
  239. private:
  240.  
  241.     public:
  242.     Fun(const char* f) : fsym(MKATOM(f)), arity(0), Arguments(NULL) {}
  243.     Fun(Sym* f) : fsym(f), arity(0), Arguments(NULL) {}
  244.     Fun(Sym* f, Term* a1) : fsym(f), arity(1), Arguments(new Term*[1]) { Arguments[0] = a1;};
  245.     Fun(Sym* f, Term* a1, Term* a2) : fsym(f), arity(2), Arguments(new Term*[2]) { Arguments[0] = a1, Arguments[1] = a2;};
  246.     Fun(Sym* f, Term* a1, Term* a2, Term* a3) : fsym(f), arity(3), Arguments(new Term*[3]) { Arguments[0] = a1, Arguments[1] = a2, Arguments[2] = a3;};
  247.     Sym* name() { return(fsym);}
  248.  
  249.     virtual void print(ostream& str) {
  250.         if(fsym == ATOM_dot) {
  251.             str << "[";
  252.             for(int i = 0; i < arity; ) {
  253.                 Arguments[i++]->print(str);
  254.                 if(Arguments[i] == NULL)             continue;
  255.                 if(i < arity)    str << "|";
  256.             }
  257.             str << "]";
  258.             return;
  259.         }
  260.         fsym->print(str);
  261.         if(arity > 0) {
  262.             str << "(";
  263.             for(int i = 0; i < arity; ) {
  264.                 Arguments[i]->print(str);
  265.                 if(++i < arity)              str << ",";
  266.             }
  267.             str << ")";
  268.         }
  269.     }
  270.     bool unifyTerm(Prolog* m, Term* t) {
  271.         return(t->unifyStructure(m, this));
  272.     }
  273.     Term* copyTerm(bool fresh, Prolog* m) {
  274.         return(copyStructure(fresh, m));
  275.     }
  276.     Fun* copyStructure(bool fresh, Prolog* m) {
  277.         return(new Fun(fresh, m, this));
  278.     }
  279.     void reset(Prolog* m) {}
  280.  
  281. private:
  282.     Fun(bool fresh, Prolog* m, Fun* p)
  283.     : fsym(p->fsym->copyAtom(m)), arity(p->arity),
  284.     Arguments(p->arity == 0 ? NULL : new Term*[p->arity]) {
  285.         for(int i = 0; i < arity; i++) Arguments[i] = p->Arguments[i]->copyTerm(fresh, m);
  286.     }
  287.     virtual bool unifyStructure(Prolog* m, Fun* t);
  288. };
  289.  
  290. class Var : public Term {
  291. private:
  292.     Term * instance;
  293.     int varno;
  294.     static int timestamp;
  295. public:
  296.     Var() : instance(this), varno(++timestamp) {
  297.     }
  298.     virtual void print(ostream& str) {
  299.         if(instance != this) instance->print(str);
  300.         else str << "_" << varno;
  301.     };
  302.     bool unifyTerm(Prolog* m, Term* t);
  303.     Term* copyTerm(bool fresh, Prolog* m);
  304.     virtual void reset(Prolog* m) {
  305.         instance = this;
  306.     }
  307.     virtual bool unifyStructure(Prolog* m, Fun* t) {
  308.         return(this->unifyTerm(m, t));
  309.     }
  310. };
  311.  
  312. int Var::timestamp = 0;
  313.  
  314. class Prog1Pred;
  315. class TermVarMapping;
  316.  
  317. class Goal {
  318. private:
  319.     Fun * head; Goal* tail;
  320. public:
  321.     Goal(Fun* h) : head(h), tail(NULL) {}
  322.     Goal(Fun* h, Goal* t) : head(h), tail(t) {}
  323.  
  324.     Goal* copyGoal(bool fresh, Prolog* m) {
  325.         return(new Goal(head->copyStructure(fresh, m), tail == NULL ? NULL : tail->copyGoal(fresh, m)));
  326.     }
  327.     Goal* appendGoal(Goal* l) {
  328.         return(new Goal(head, tail == NULL ? NULL : tail->appendGoal(l)));
  329.     }
  330.     virtual void print(ostream& str) { head->print(str); if(tail != NULL) {
  331.             str << "; "; tail->print(str);
  332.         }}
  333.     virtual bool unifyGoal_Unused(Prolog* m, Goal* c2);
  334.     int solve(Prolog* m, Prog1Pred* p, bool interactive, int results, int level, TermVarMapping* map);
  335. };
  336.  
  337. class Prolog {
  338. private:
  339.     Var * tcar; Prolog* sofar;
  340.     Prolog(Var* h, Prolog* t) : tcar(h), sofar(t) {
  341.     }
  342.  
  343. public:
  344.     Prolog() : tcar(NULL), sofar(NULL) {
  345.     }
  346.     Prolog* Note() {
  347.         return(sofar);
  348.     }
  349.     Prolog* Push(Var* x) {
  350.         return(sofar = new Prolog(x, sofar));
  351.     }
  352.     void Undo(Prolog* whereto) {
  353.         for(; sofar != whereto; sofar = sofar->sofar)            sofar->tcar->reset(this);
  354.     }
  355. };
  356.  
  357. class Clause {
  358. public:
  359.     Fun * head; Goal* body;
  360.     Clause(Fun* h, Goal* t) : head(h), body(t) {}
  361.     Clause(Fun* h, Fun* t) : head(h), body(new Goal(t)) {}
  362.     Clause(Fun* h) : head(h), body(NULL) {}
  363.     virtual ostream& operator<<(ostream& str) {
  364.         print(str); return(str);
  365.     }
  366.  
  367.     virtual Clause* copyClause(bool fresh, Prolog* m) {
  368.         return(new Clause(head->copyStructure(fresh, m), body == NULL ? NULL : body->copyGoal(fresh, m)));
  369.     }
  370.  
  371.     bool unifyTerm_Unused(Prolog* m, Clause* c2) {
  372.         Prolog* mark = m->Note();
  373.         if(!(head->unifyTerm(m, c2->head) && body->unifyGoal_Unused(m, c2->body))) {
  374.             m->Undo(mark);
  375.             return(false);
  376.         }
  377.         return(true);
  378.     }
  379.  
  380.     virtual Clause* copyForEdit() {
  381.         auto tv = new Prolog();
  382.         auto tvm = tv->Note();
  383.         Clause* c3 = copyClause(false, tv);
  384.         auto newtvm = tv->Note();
  385.         if(newtvm != tvm) {
  386.             // secretly this shouldnt really happen with copyClause(false, tv);
  387.             tv->Undo(tvm);
  388.         }
  389.         return(c3);
  390.     }
  391.  
  392.     virtual void print(ostream& str) {
  393.         head->print(str);  str << " :- ";
  394.         if(body == NULL) {
  395.             str << "true";
  396.         } else {
  397.             body->print(str);
  398.         }
  399.     }
  400.  
  401.     Goal* appendBody(Fun* l) {
  402.         Goal* item = new Goal(l);
  403.         if(body == NULL) {
  404.             body = item;
  405.         } else {
  406.             body->appendGoal(item);
  407.         }
  408.         return(item);
  409.     }
  410.  
  411. };
  412.  
  413. class Prog1Pred {
  414. public:
  415.     Clause * pcar; Prog1Pred* pcdr;
  416.     Prog1Pred(Clause* h) : pcar(h), pcdr(NULL) {}
  417.     Prog1Pred(Clause* h, Prog1Pred* t) : pcar(h), pcdr(t) {}
  418.     Prog1Pred(Clause* h, Clause* t) : pcar(h), pcdr(new Prog1Pred(t)) {}
  419.     Prog1Pred(Clause* h, Clause* h2, Clause* t) : pcar(h), pcdr(new Prog1Pred(h2, t)) {}
  420.  
  421.     /* returns the newly appended Prog1Pred*/
  422.     Prog1Pred* appendStatement(Clause* l) {
  423.         if(pcdr != NULL) return(pcdr->appendStatement(l));
  424.         pcdr = new Prog1Pred(l);
  425.         return(pcdr);
  426.     }
  427.  
  428.     /* returns itself*/
  429.     Prog1Pred* prependStatement(Clause* h) {
  430.         pcdr = new Prog1Pred(pcar, pcdr);
  431.         pcar = h;
  432.         return(this);
  433.     }
  434.  
  435. };
  436.  
  437. bool Goal::unifyGoal_Unused(Prolog* m, Goal* c2) {
  438.     Prolog* mark = m->Note();
  439.     if(!(head->unifyTerm(m, c2->head) && tail->unifyGoal_Unused(m, c2->tail))) {
  440.         m->Undo(mark);
  441.         return(false);
  442.     }
  443.     return(true);
  444. }
  445.  
  446.  
  447. bool Fun::unifyStructure(Prolog* m, Fun* t) {
  448.     Prolog* mark = m->Note();
  449.     if(!(arity == t->arity && fsym->eqatom(t->fsym))) {
  450.         m->Undo(mark); return(false);
  451.     }
  452.     for(int i = 0; i < arity; i++) if(!Arguments[i]->unifyTerm(m, t->Arguments[i])) {
  453.             m->Undo(mark); return(false);
  454.         }
  455.     return(true);
  456. };
  457.  
  458. bool Var::unifyTerm(Prolog* m, Term* t) {
  459.     if(instance != this) return(instance->unifyTerm(m, t));m->Push(this); instance = t; return(true);
  460. }
  461. Term* Var::copyTerm(bool fresh, Prolog* m) {
  462.     if(instance == this) {
  463.         if(!fresh) return(this);
  464.         m->Push(this);
  465.         instance = new Var();
  466.         return(instance);
  467.     }
  468.     return(instance);
  469. }
  470.  
  471.  
  472. class TermVarMapping {
  473. private:
  474.     Var * * varvar;
  475.     const char** vartext;
  476.     int size;
  477. public:
  478.     TermVarMapping(Var* vv[], const char* vt[], int vs)
  479.     :varvar(vv), vartext(vt), size(vs) {
  480.     }
  481.     void showanswer(ostream& str) {
  482.         if(size == 0)            str << "yes\n";
  483.         else {
  484.             for(int i = 0; i < size; i++) {
  485.                 str << vartext[i] << " = "; varvar[i]->print(str); str << "\n";
  486.             }
  487.         }
  488.     }
  489. };
  490.  
  491. Fun* NIL = CC(ATOM_nil);
  492. Sym* ATOM_cut = MKATOM("!");
  493. Fun* CUT = CC(ATOM_cut);
  494.  
  495. int Goal::solve(Prolog* m, Prog1Pred* p, bool interactive, int results, int level, TermVarMapping* map) {
  496.     std::string line = "";
  497.     ostream& str = cout;
  498.     bool cutted = false;
  499.     bool success = false;
  500.     DEBUG(SOLVE,{ indent(level); str << "solve@" << level << ": ";
  501.              this->print(str); str << "\n";});
  502.  
  503.     for(Prog1Pred* q = p; q != NULL; q = q->pcdr) {
  504.         Prolog* t = m->Note();
  505.         Clause* c = q->pcar->copyClause(true, m);
  506.         int nextLevel = 1;
  507.         m->Undo(t);
  508.         DEBUG(SOLVE,{ indent(level); str << "  try:"; c->print(str); str << "\n";});
  509.         if(head->unifyTerm(m, c->head)) {
  510.             Goal* gdash = c->body == NULL ?  tail :  (nextLevel = 0,
  511.                                                                                                 c->body->appendGoal(tail));
  512.             if(gdash != NULL) {
  513.                 if(gdash->head->name() == ATOM_cut) {
  514.                     gdash = NULL;
  515.                     cutted = true;
  516.                 }
  517.             }
  518.             if(gdash == NULL) {
  519.                 success = true;
  520.                 results++;
  521.                 map->showanswer(str);        
  522.                 if(interactive) {
  523.                     std::cout << "(ENTER) - next solution \t (stop+ENTER) - stop finding solution" << std::endl;
  524.                     std::getline(std::cin, line);
  525.                 }
  526.             } else {
  527.                 int waz = gdash->solve(m, p,interactive,results, level + nextLevel, map);
  528.                 if(waz == 0) {
  529.                     DEBUG(SOLVE,{ indent(level); str << "  parent fails.\n";});
  530.                 }
  531.             }
  532.         } else {
  533.             DEBUG(SOLVE,{ indent(level); str << "  nomatch.\n";});
  534.             if(interactive) {
  535.                 if(results!=0) {
  536.                     std::cout << "(ENTER) no more solutions" << std::endl;
  537.                     std::getline(std::cin, line);
  538.                 }
  539.             }
  540.         }
  541.         if(cutted) break;
  542.         m->Undo(t);
  543.         if(line == "stop") break;
  544.     }
  545.     return(results);
  546. }
  547.  
  548. class SymValueMap : public Sym {
  549.     SymMap* dataValue;
  550.     const char* MYTYPE = "MAP";
  551. public:
  552.     virtual const char* typeName() { return(MYTYPE);}
  553.     SymValueMap() : dataValue(new SymMap()) {}
  554.     SymValueMap(SymMap* s) : dataValue(s) {}   
  555.  
  556.     virtual void print(ostream& str) {
  557.         str <<  "'" ;
  558.         str << dataValue;
  559.         str << "'";
  560.     }
  561.  
  562.     virtual Sym* copyAtom(Prolog* m) {
  563.         return(new SymValueMap(dataValue));
  564.     }
  565.  
  566.     virtual bool eqatom(Sym* t) {
  567.       if(typeName() != MYTYPE) return(false);
  568.         return(strcmp(c_str(), t->c_str()) == 0);
  569.     }
  570.  
  571.     // Might store preds here?
  572.     // std::vector<Prog1Pred*> preds = std::vector<Prog1Pred*>(33);
  573.  
  574. };
  575.  
  576.  
  577. #ifdef LISP90
  578. #else
  579.  
  580. #define to_string(X) X
  581. #define read_atom(X) X
  582.  
  583. #define nonvar SymMap
  584. #endif
  585.  
  586. class SymCell : public Sym {
  587.     nonvar* dataValue;
  588.  
  589.     const char* MYTYPE = "LISP90";
  590. public:
  591.     virtual const char* typeName() { return(MYTYPE);}
  592.     SymCell() : dataValue(new nonvar()) {}
  593.     SymCell(nonvar* s) : dataValue(s) {}   
  594.    
  595. #ifdef LISP90
  596.     SymCell(const char* s) : dataValue(read_atom(s)) {}
  597. #endif
  598.  
  599.     virtual void print(ostream& str) {
  600.         str <<  "'" ;
  601.         str << to_string(dataValue);
  602.         str << "'";
  603.     }
  604.  
  605.     virtual Sym* copyAtom(Prolog* m) {
  606.         return(new SymValueMap(dataValue));
  607.     }
  608.  
  609.     virtual bool eqatom(Sym* t) {
  610.       if(typeName() != MYTYPE) return(false);
  611.         return(strcmp(c_str(), t->c_str()) == 0);
  612.     }
  613.  
  614.     // Might store preds here?
  615.     // std::vector<Prog1Pred*> preds = std::vector<Prog1Pred*>(33);
  616.  
  617. };
  618.  
  619.  
  620. /* A sample test program: append*/
  621. int test_program_append_prev(bool interactive) {
  622.     ostream& str = cout;
  623.  
  624.     Sym* at_app = MKATOM("append_3");
  625.     Sym* at_cons = MKATOM(".");
  626.     Fun* f_nil = new Fun(MKATOM("[]"));
  627.     Fun* f_1 = new Fun(MKATOM("1"));
  628.     Fun* f_2 = new Fun(MKATOM("2"));
  629.     Fun* f_3 = new Fun(MKATOM("3"));
  630.  
  631.     Term* v_x = new Var();
  632.     Fun* lhs1 = new Fun(at_app, f_nil, v_x, v_x);
  633.     Clause* c1 = new Clause(lhs1);
  634.  
  635.     Term* v_l = new Var();
  636.     Term* v_m = new Var();
  637.     Term* v_n = new Var();
  638.     Fun* rhs2 = new Fun(at_app, v_l, v_m, v_n);
  639.     Fun* lhs2 = new Fun(at_app, new Fun(at_cons, v_x, v_l),
  640.                                             v_m,
  641.                                             new Fun(at_cons, v_x, v_n));
  642.     Clause* c2 = new Clause(lhs2, new Goal(rhs2, NULL));
  643.  
  644.     Var* v_i = new Var();
  645.     Var* v_j = new Var();
  646.     Fun* rhs3 = new Fun(at_app, v_i, v_j,
  647.                                             new Fun(at_cons, f_1,
  648.                                                             new Fun(at_cons, f_2,
  649.                                                                             new Fun(at_cons, f_3, f_nil))));
  650.  
  651.     Goal* g1 = new Goal(rhs3, NULL);
  652.  
  653.     Prog1Pred* test_p = new Prog1Pred(c1, new Prog1Pred(c2));
  654.     Prog1Pred* test_p2 = new Prog1Pred(c2, new Prog1Pred(c1));
  655.  
  656.     Var* varvar[] = { v_i, v_j};
  657.     const char* varname[] = { "I", "J"};
  658.     TermVarMapping* var_name_map = new TermVarMapping(varvar, varname, 2);
  659.  
  660.     Prolog* m = new Prolog();
  661.     str << "=D=======Append with normal clause order:\n";
  662.     g1->solve(m, test_p,true, 0,0, var_name_map);
  663.     str << "\n=E=======Append with reversed normal clause order:\n";
  664.     g1->solve(m, test_p2,true, 0,0, var_name_map);
  665.     return(0);
  666. }
  667.  
  668. #ifndef LISP90
  669. int main(int argc, char* argv[]) {
  670.     test_program_append( true);
  671.     test_program_append_prev( true);
  672. }
  673. #endif
  674.  
  675.  
  676. /* A sample test program: append*/
  677.  
  678. int test_program_append(bool interactive) {
  679.     ostream& str = cout;
  680.     /*Psuedovars for source translation */
  681.     PSUEDOVAR(X);
  682.     PSUEDOVAR(L);
  683.     PSUEDOVAR(M);
  684.     PSUEDOVAR(N);
  685.     PSUEDOVAR(I);
  686.     PSUEDOVAR(J);
  687.  
  688.  
  689.     Sym* APPEND3 = MKATOM("append_3");
  690.  
  691.  
  692.  
  693.  
  694.     /* append_3([],X,X). */
  695.     Clause* c1 = FACT(CC(APPEND3, NIL, VAR_X, VAR_X));
  696.     /*  append([X|LL],M,[X|N]):- append(LL,M,N). */
  697.     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));
  698.  
  699.  
  700.     /*
  701.                      Test normally:
  702.  
  703.                                     append_3([],X,X).
  704.                                     append([X|LL],M,[X|N]):- append(LL,M,N).
  705.     */
  706.     Prog1Pred* test_program_normally = new Prog1Pred(c1, c2);
  707.  
  708.  
  709.     /*
  710.                     Test reversed:
  711.  
  712.                                     append([X|LL],M,[X|N]):- append(LL,M,N).
  713.                                     append_3([],X,X).
  714.     */
  715.     Prog1Pred* test_program_reversed = new Prog1Pred(c2, c1);
  716.  
  717.  
  718.     /*
  719.                      Test Cat:
  720.  
  721.                                     append_3([],X,X):- !.
  722.                                     append([X|LL],M,[X|N]):- append(LL,M,N).
  723.     */
  724.  
  725.     // #undef USE_CUT
  726.  
  727.  
  728.     cout << "\n"; cout << "\n"; cout << "\n"; cout << "\n";
  729.     c1->print(cout);
  730.     cout << "\n"; cout << "\n"; cout << "\n"; cout << "\n";
  731.  
  732. #ifdef USE_CUT
  733.     Clause* c3 = c1->copyForEdit();
  734.  
  735.     c3->appendBody(CUT);
  736.  
  737.     Prog1Pred* test_program_cut = new Prog1Pred(c3, c2);
  738.  
  739.     cout << "\n"; cout << "\n"; cout << "\n"; cout << "\n";
  740.     c1->print(cout);
  741.     cout << "\n"; cout << "\n"; cout << "\n"; cout << "\n";
  742.  
  743.     cout << "\n"; cout << "\n"; cout << "\n"; cout << "\n";
  744.     c3->print(cout);
  745.     cout << "\n"; cout << "\n"; cout << "\n"; cout << "\n";
  746.  
  747. #endif
  748.  
  749.  
  750.     Var* varvar[] = { VAR_I,VAR_J};
  751.     const char* varname[] = { "I", "J"};
  752.     TermVarMapping* var_name_map = new TermVarMapping(varvar, varname, 2);
  753.  
  754.     /*
  755.                      ?- append_3(I,J,[1,2,3]).
  756.     */
  757.     Goal* g1 = new Goal(CC(APPEND3, VAR_I, VAR_J, LL(CC("1"), LL(CC("2"), LL(CC("3"), NIL)))));
  758.  
  759.     Prolog* m = new Prolog();
  760.  
  761.     str << "=A=======Append with normal clause order:\n";
  762.     g1->solve(m, test_program_normally, true, 0,0, var_name_map);
  763.  
  764.     str << "\n=B========Append with reversed normal clause order:\n";
  765.     g1->solve(m, test_program_reversed, true, 0,0, var_name_map);
  766.  
  767. #ifdef USE_CUT
  768.     str << "\n=C=======Append with a cut:\n";
  769.     g1->solve(m, test_program_cut, true, 0, 0,var_name_map);
  770. #endif
  771.     return(0);
  772. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement