Advertisement
logicmoo

Untitled

Jul 29th, 2018
679
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Prolog 7.79 KB | None | 0 0
  1.  
  2. /* prolog.c: a simple Prolog interpreter written in C++,               */
  3. /*           including an example test run as main().                  */
  4. /* Copyright (c) Alan Mycroft, University of Cambridge, 2000.          */
  5. /*
  6.  
  7.   original from https://www.cl.cam.ac.uk/~am21/research/funnel/prolog.c
  8.  
  9.   Dmiles made trhe trail non static
  10.  
  11. */
  12. #define C_TEXT( text ) ((char*)std::string( text ).c_str())
  13. #undef C_TEXT
  14. #define C_TEXT( text ) ((char*)text)
  15.  
  16. #include <iostream>
  17. using namespace std;
  18. #include <string.h>
  19.  
  20. void indent(int n) {
  21.   for ( int i = 0; i<n; i++ ) cout << "    ";
  22. }
  23.  
  24. class TermCons;
  25. class Trail;
  26.  
  27. class Term {
  28. public:
  29.   virtual void print() = 0;
  30.   virtual bool unify(Trail* ,Term* ) = 0;
  31.   virtual bool unify2(Trail* , TermCons* ) = 0;
  32.   virtual Term* copy(Trail* ) = 0;
  33.   virtual void reset() = 0;
  34. };
  35.  
  36. class Trail {
  37. private:
  38.   Term* tcar;
  39.   Trail* tcdr;
  40.   Trail* sofar;
  41.   Trail(Term* h, Trail* t) : tcar(h), tcdr(t) {
  42.   }
  43. public:
  44.   Trail() : tcar(NULL), tcdr(NULL) {
  45.   }
  46.  
  47.   Trail* Note() {
  48.     return sofar;
  49.   }
  50.   void Push(Term* x) {
  51.     sofar = new Trail(x, sofar);
  52.   }
  53.   void Undo(Trail* whereto) {
  54.     for ( ; sofar != whereto; sofar = sofar->tcdr )
  55.       sofar->tcar->reset();
  56.   }
  57. };
  58.  
  59.  
  60. class Atom {
  61.   char* atomname;
  62. public: Atom(char* s) : atomname(s) {
  63.   }
  64.   void print() {
  65.     cout<<atomname;
  66.   }
  67.   bool eqatom(Atom* t) {
  68.     return strcmp(atomname, t->atomname) == 0;
  69.   }
  70. };
  71.  
  72.  
  73. Atom* NIL = new Atom(C_TEXT("[]"));
  74. Atom* CONSLST = new Atom(C_TEXT("."));
  75.  
  76.  
  77. class TermCons : public Term {
  78. private:
  79.   int arity;
  80.   Atom* fsym;
  81.   Term** args;
  82. public:
  83.   TermCons(Atom* f)
  84.   : fsym(f), arity(0), args(NULL) {
  85.   }
  86.   TermCons(Atom* f, Term* a1)
  87.   : fsym(f), arity(1), args(new Term*[1]) {
  88.     args[0]=a1;
  89.   };
  90.   TermCons(Atom* f, Term* a1, Term* a2)
  91.   : fsym(f), arity(2), args(new Term*[2]) {
  92.     args[0]=a1, args[1]=a2;
  93.   };
  94.   TermCons(Atom* f, Term* a1, Term* a2, Term* a3)
  95.   : fsym(f), arity(3), args(new Term*[3]) {
  96.     args[0]=a1, args[1]=a2, args[2]=a3;
  97.   };
  98.  
  99.   void printList() {
  100.     cout <<"[";
  101.     for ( int i = 0; i<arity; ) {
  102.       args[i++]->print();      
  103.       if ( args[i] == NULL ) continue;
  104.       if ( i < arity ) cout << "|";
  105.     }
  106.     cout <<"]";
  107.   }
  108.  
  109.  
  110.   void print() {
  111.     if ( fsym==CONSLST ) {
  112.       printList();
  113.       return;
  114.     }
  115.     fsym->print();
  116.     if ( arity>0 ) {
  117.       cout <<"(";
  118.       for ( int i = 0; i<arity; ) {
  119.         args[i]->print();
  120.         if ( ++i < arity ) cout << ",";
  121.       }
  122.       cout <<")";
  123.     }
  124.   }
  125.   bool unify(Trail* mach,Term* t) {
  126.     return t->unify2(mach,this);
  127.   }
  128.   Term* copy(Trail* mach) {
  129.     return copy2(mach);
  130.   }
  131.   TermCons* copy2(Trail* mach) {
  132.     return new TermCons(mach,this);
  133.   }
  134.   virtual void reset() {
  135.   }
  136. private:
  137.   TermCons(Trail* mach, TermCons* p)
  138.   : fsym(p->fsym), arity(p->arity),
  139.   args(p->arity==0 ? NULL : new Term*[p->arity]) {
  140.     for ( int i=0; i<arity; i++ ) args[i] = p->args[i]->copy(mach);
  141.   }
  142.  
  143.   bool unify2(Trail* mach, TermCons* t) {
  144.     if ( !(fsym->eqatom(t->fsym) && arity == t->arity) )
  145.       return false;
  146.     for ( int i = 0; i<arity; i++ )
  147.       if ( !args[i]->unify(mach,t->args[i]) ) return false;
  148.     return true;
  149.   }
  150.  
  151.  
  152. };
  153.  
  154. class TermVar : public Term {
  155. private:
  156.   Term* instance;
  157.   int varno;
  158.   static int timestamp;
  159. public:
  160.   TermVar() : instance(this), varno(++timestamp) {
  161.   }
  162.   void print() {
  163.     if ( instance!=this ) instance->print();
  164.     else cout<<"_"<<varno;
  165.   };
  166.   bool unify(Trail* mach, Term* t);
  167.   Term* copy(Trail* mach);
  168.   virtual void reset() {
  169.     instance = this;
  170.   }
  171. private:
  172.   bool unify2(Trail* mach,TermCons* t) {
  173.     return this->unify(mach,t);
  174.   }
  175. };
  176.  
  177. int TermVar::timestamp = 0;
  178.  
  179. class Program;
  180. class TermVarMapping;
  181.  
  182. class Goal {
  183. private:
  184.   TermCons* car;
  185.   Goal* cdr;
  186.   Trail* mach;
  187.  
  188. public:
  189.   Goal(TermCons* h, Goal* t) : car(h), cdr(t) {
  190.     mach = new Trail();
  191.   }
  192.   Goal* copy(Trail* mach) {
  193.     return new Goal(car->copy2(mach),
  194.                     cdr==NULL ? NULL : cdr->copy(mach));
  195.   }
  196.   Goal* append(Goal* l) {
  197.     return new Goal(car,
  198.                     cdr==NULL ? NULL : cdr->append(l));
  199.   }
  200.   void print() {
  201.     car->print();
  202.     if ( cdr != NULL ) {
  203.       cout << "; ", cdr->print();
  204.     }
  205.   }
  206.   void solve(Program* p, int level, TermVarMapping* map);
  207. };
  208.  
  209. class Clause {
  210. public:
  211.   TermCons* head;
  212.   Goal* body;
  213.   Clause(TermCons* h, Goal* t) : head(h), body(t) {
  214.   }
  215.   Clause* copy(Trail* mach) {
  216.     return new Clause(head->copy2(mach),
  217.                       body==NULL ? NULL : body->copy(mach));
  218.   }
  219.   void print() {
  220.     head->print();
  221.     cout << " :- ";
  222.     if ( body==NULL ) cout << "true";
  223.     else body->print();
  224.   }
  225. };
  226.  
  227. class Program {
  228. public:
  229.   Clause* pcar;
  230.   Program* pcdr;
  231.   Program(Clause* h, Program* t) : pcar(h), pcdr(t) {
  232.   }
  233. };
  234.  
  235. bool TermVar::unify(Trail* mach,Term* t) {
  236.   if ( instance!=this ) return instance->unify(mach,t);
  237.   mach->Push(this); instance = t; return true;
  238. }
  239.  
  240. Term* TermVar::copy(Trail* mach) {
  241.   if ( instance==this ) {
  242.     mach->Push(this); instance = new TermVar();
  243.   }
  244.   return instance;
  245. }
  246.  
  247. class TermVarMapping {
  248. private:
  249.   TermVar* *varvar;
  250.   char* *vartext;
  251.   int size;
  252. public:
  253.   TermVarMapping(TermVar* vv[], char* vt[], int vs)
  254.   :varvar(vv), vartext(vt), size(vs) {
  255.   }
  256.   void showanswer() {
  257.     if ( size == 0 ) cout << "yes\n";
  258.     else {
  259.       for ( int i = 0; i < size; i++ ) {
  260.         cout << vartext[i] << " = "; varvar[i]->print(); cout << "\n";
  261.       }
  262.     }
  263.   }
  264. };
  265.  
  266. void Goal::solve(Program* p, int level, TermVarMapping* map) {
  267.   indent(level); cout << "solve@"  << level << ": ";
  268.   this->print(); cout << "\n";
  269.   for ( Program* q = p; q != NULL; q = q->pcdr ) {
  270.     Trail* t = mach->Note();
  271.     Clause* c = q->pcar->copy(mach);
  272.     mach->Undo(t);
  273.     indent(level); cout << "  try:"; c->print(); cout << "\n";
  274.     if ( car->unify(mach,c->head) ) {
  275.       Goal* gdash = c->body==NULL ? cdr : c->body->append(cdr);
  276.       if ( gdash == NULL ) map->showanswer();
  277.       else gdash->solve(p, level+1, map);
  278.     } else {
  279.       indent(level); cout << "  nomatch.\n";
  280.     }
  281.     mach->Undo(t);
  282.   }
  283. }
  284.  
  285. /* A sample test program: append*/
  286. int main(int argc, char* argv[]) {
  287.  
  288.   Atom* at_app = new Atom(C_TEXT("append_3"));
  289.  
  290.   TermCons* f_nil = new TermCons(NIL);
  291.  
  292.   Term* v_x = new TermVar();
  293.   TermCons* lhs1 = new TermCons(at_app, f_nil, v_x, v_x);
  294.   Clause* c1 = new Clause(lhs1, NULL);
  295.  
  296.   Term* v_l = new TermVar();
  297.   Term* v_m = new TermVar();
  298.   Term* v_n = new TermVar();
  299.   TermCons* rhs2 = new TermCons(at_app, v_l, v_m, v_n);
  300.   TermCons* lhs2 = new TermCons(at_app, new TermCons(CONSLST, v_x, v_l),
  301.                                 v_m,
  302.                                 new TermCons(CONSLST, v_x, v_n));
  303.   Clause* c2 = new Clause(lhs2, new Goal(rhs2,NULL));
  304.  
  305.   Program* test_p = new Program(c1, new Program(c2, NULL));
  306.   Program* test_p2 = new Program(c2, new Program(c1, NULL));
  307.  
  308.  
  309.  
  310.   TermVar* v_i = new TermVar();
  311.   TermVar* v_j = new TermVar();
  312.   TermVar* varvar[] = {v_i, v_j};
  313.   char* varname[] =  {C_TEXT("I"), C_TEXT("J")};
  314.   TermVarMapping* var_name_map = new TermVarMapping(varvar, varname, 2);
  315.  
  316.   TermCons* rhs3 = new TermCons(at_app, v_i, v_j,
  317.                                 new TermCons(CONSLST, new TermCons(new Atom(C_TEXT("1"))),
  318.                                              new TermCons(CONSLST, new TermCons(new Atom(C_TEXT("2"))),
  319.                                                           new TermCons(CONSLST, new TermCons(new Atom(C_TEXT("3"))), f_nil))));
  320.  
  321.   Goal* g1 = new Goal(rhs3, NULL);
  322.  
  323.   cout << "=======Append with normal clause order:\n";
  324.   g1->solve(test_p, 0, var_name_map);
  325.   cout << "\n=======Append with reversed normal clause order:\n";
  326.   g1->solve(test_p2, 0, var_name_map);
  327.   return 0;
  328. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement