My attempt at making a Artificial Intelligence Program

Click For Summary
SUMMARY

The discussion focuses on a personal project involving the development of an artificial intelligence program named "logician," which processes syllogisms. The program accepts user input in the form of logical statements, such as "No dogs are cats" and "All cats are animals," and generates conclusions like "Some animals are not dogs." The implementation is done in C++ using the file Logic2006.cpp, which includes various logical constructs and string manipulations to derive conclusions from the input statements.

PREREQUISITES
  • C++ programming, specifically knowledge of string manipulation and control structures.
  • Understanding of logical syllogisms and propositional logic.
  • Familiarity with C++ standard libraries, particularly iostream and string.
  • Basic knowledge of compiling and running C++ programs.
NEXT STEPS
  • Explore advanced C++ features such as classes and object-oriented programming to enhance the program's structure.
  • Learn about logical reasoning algorithms to improve the AI's inference capabilities.
  • Investigate natural language processing techniques for better input handling and understanding.
  • Study design patterns in software development to optimize the program's architecture.
USEFUL FOR

This discussion is beneficial for computer science students, aspiring AI developers, and anyone interested in the intersection of logic and programming, particularly in C++. It provides insights into practical applications of logic in software development.

kmarinas86
Messages
974
Reaction score
1
My attempt at making an Artificial Intelligence Program

Hi. I would like some comments on my artificial "logician". So far it is limited to syllogisms, where you type in a phrases such as "No dogs are cats" and "All cats are animals" and then the program prints out phrases such as "Some animals are not dogs". There is a more impressive demonstration of an earlier version of this program in the attached image.

I am a sophomore at the University of Houston, and I plan to major in Computer Science with a minor in Physics and Math.

Logic2006.cpp

Code:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;

#include "globalvariables.h"

void printout();

main()
{
    system("PAUSE");
    cout<<"LOGIC 2006\n";
    cout<<"When you type a \".\" anywhere, you have finished the sentence.\n";
    cout<<"After last sentence, type \"zzz\" to end program.\n";
    i=0;
    while(1)
    {
      k=1;
      r=0;
      
      bool S,A,N,T;
      p=&s.s[++so];
        
      do
      {
          r++;
          cin>>c;
          
          if(strcmp(c,"zzz")==0){ printout(); system("PAUSE"); exit (1);}   
          bool some=(strcmp(c,"Some")==0|strcmp(c,"some")==0|
          strcmp(c,"Most")==0|strcmp(c,"most")==0); // I
          bool all=(strcmp(c,"All")==0|strcmp(c,"all")==0); // A
          bool no=(strcmp(c,"No")==0|strcmp(c,"no")==0); // E
          bool n0t=(strcmp(c,"Not")==0|strcmp(c,"not")==0); // O
          bool of=strcmp(c,"of")==0;
          bool the=strcmp(c,"the")==0;
          bool linking=strcmp(c,"are")==0|strcmp(c,"is")==0|strcmp(c,"was")==0|
          strcmp(c,"was")==0|strcmp(c,"were")==0|strcmp(c,"have")==0|
          strcmp(c,"been")==0,
          iF=strcmp(c,"If")==0|strcmp(c,"if")==0,
          then=strcmp(c,"Then")==0|strcmp(c,"then")==0;
                    
          char * pch=c;
          
          pch=strtok(c,".;:!?");
          
          if(some){ k=0; S=true; A=false; N=false; T=false; }
          if(all|iF){ k=0; S=false; A=true; N=false; T=false; }
          if(no){ k=0; S=false; A=false; N=true; T=false; }
          if(n0t){ k=0; S=false; A=false; N=false; T=true; }
          if(then){ k=2; }
          
          if(k==0)
          {
             if(S){ p=&s.s[++so]; }
             if(A|iF){ p=&s.a[++al]; }
             if(N){ p=&s.n[++n0]; }
             if(T){ p=&s.t[++nt]; }
          }    
         
          t=k;
          
          if(k==0)
          {  
                  strcat(p->a,c);
                  k++;
          }    
          else if(k==1)
              if(linking|n0t|then)
                  k++;
              else
              {
                  if(r>1) strcat(p->b," ");
                  strcat(p->b,c);
              }    
          if(k==2)
              if(linking|n0t|then)
              {
                  if(r>1) strcat(p->c," ");
                  strcat(p->c,c);
              }    
              else
                  k++;
          if(k==3)
          {
             if(r>1) strcat(p->d," ");
             strcat(p->d,c);
          }    

          if(t<k) r==0;
          
      }
      while(strcspn(c,".?!")==strlen(c));

      s.f++;
    }
    system("PAUSE");
}

int match(const char * b,const char * d,char c, int limit)
{
    for(int k=0;k<=limit;k++)
    {
        if(c=='S')
            p3=&s.s[k];
        if(c=='A')
            p3=&s.a[k];
        if(c=='N')
            p3=&s.n[k];
        if(c=='T')
            p3=&s.t[k];
        const char
        *zb=const_cast<char *>(p3->b),
        *zd=const_cast<char *>(p3->d);
        if(strcmp(b,zb)==0&&strcmp(d,zd)==0)
        {
           return 1;
        }    
    }
    return 0;        
}            

void printout()
{
    while(i<=al)
    {
       p=&s.a[i];
       const char
       *xb=const_cast<char *>(p->b),
       *xd=const_cast<char *>(p->d);
       j=0;
       while(j<=al)
       {
          if(i!=j)
          {
              p2=&s.a[j];
              const char
              *yb=const_cast<char *>(p2->b),
              *yd=const_cast<char *>(p2->d);
              if(strcmp(xb,yd)==0&&match(yb,xd,'A',al)==0)
              {
                  al++;
                  p3=&s.a[al];
                  strcpy(p3->a,p2->a);
                  strcpy(p3->b,p2->b);
                  strcpy(p3->c,p2->c);
                  strcpy(p3->d,p->d); 
                  cout<<p2->a<<yb<<p2->c<<xd<<"."<<endl;
              }    
              if(strcmp(yb,xd)==0&&match(xb,yd,'A',al)==0)
              {
                  al++;
                  p3=&s.a[al];
                  strcpy(p3->a,p->a);
                  strcpy(p3->b,p->b);
                  strcpy(p3->c,p->c);
                  strcpy(p3->d,p2->d);
                  cout<<p->a<<xb<<p->c<<yd<<"."<<endl;
              }
          }    
          j++;   
       }    
       j=0;
       while(j<=so)
       {
          if(i!=j)
          {
              p2=&s.s[j];
              const char
              *yb=const_cast<char *>(p2->b),
              *yd=const_cast<char *>(p2->d);
              if(strcmp(xb,yd)==0&&match(yb,xd,'S',so)==0)
              {
                  so++;
                  p3=&s.a[so];
                  strcpy(p3->a,p2->a);
                  strcpy(p3->b,p2->b);
                  strcpy(p3->c,p2->c);
                  strcpy(p3->d,p->d);
                  cout<<p2->a<<yb<<p2->c<<xd<<"."<<endl;
              }
          }    
          j++;
       }
       j=0;
       while(j<=n0)
       {
          if(i!=j)
          {
              p2=&s.n[j];
              const char
              *yb=const_cast<char *>(p2->b),
              *yd=const_cast<char *>(p2->d);
              if(strcmp(xb,yd)==0&&match(yb,xd,'N',n0)==0)
              {
                  so++;
                  p3=&s.a[so];
                  strcpy(p3->a,"Some ");
                  strcpy(p3->b,p2->b);
                  strcpy(p3->c,p2->c);
                  char temp[50]="not ";
                  strcpy(temp,"not ");
                  strcpy(temp,p->d);
                  strcpy(p3->d,temp);
                  cout<<"Some"<<xd<<p->c<<" not"<<yb<<"."<<endl;
              }
          }    
          j++;
       }
       i++;
    }    
}
globalvariables.h

Code:
const int sml=30;
const int lrg=50;

class SentForm
{
  public:
  char a[lrg], b[lrg], c[lrg], d[lrg];
  int w;
  char type;
};

class Sentences
{
  public:
  SentForm s[sml], a[sml], n[sml], t[sml];
  int f;
};int i,j,k,l,r,t,al=-1,so=-1,n0=-1,nt=-1,wo=0;
char type,c[lrg],temp[lrg];
char * pch;

SentForm *p,*p2,*p3;
Sentences s;

And this is the old version:

logic.cpp

Code:
// stringstreams
#include <iostream>
#include <string>
#include <sstream>
using namespace std;

const int size=300;

class IfThen
{
    public: char a[size]; char b[size]; char c[size]; char i1[size]; char i2[size];
};

class Some
{
    public: char a[size]; char b[size]; char m[size];
};

class All
{
    public: char a[size]; char b[size]; char m[size];
};

class ClaimReason
{
    public: char a[size]; char b[size]; char c[size];
};

class Mem
{
    public: char a[size]; char b[size];
};

class n0t
{
    public: char w[size];
};

int main ()
{
  char c[size];
  do
  {
      int i,j,re,it,so,al,no,is,ntt,isb,mi,k,ksome,kall;
      re=it=so=al=no=-1;
      mi=k=ksome=kall=is=ntt=0;
      ClaimReason claimreason[size];
      IfThen ifthen[size];
      Some some[size];
      All all[size];
      Mem memory[size];
      n0t nOt[size];
      for(int i=0;i<size;i++)
      {
          strcpy(claimreason[i].a,"");
          strcpy(claimreason[i].b,"");
          strcpy(ifthen[i].a,"");
          strcpy(ifthen[i].b,"");
          strcpy(ifthen[i].c,"");
          strcpy(some[i].a,"");
          strcpy(some[i].b,"");
          strcpy(all[i].a,"");
          strcpy(all[i].b,"");      
          strcpy(nOt[i].w,"");      
          strcpy(memory[i].a,"");
          strcpy(memory[i].b,"");
      }
      bool end,bre,bcd,bcs,bso,bal,bis,kso,kar,kal,kis,mod,bnt,sent;
      sent=end=bre=bcd=bcs=bso=bal=bis=kso=kar=kal=kis=mod=bnt=sent=0;
      do
      {    
          char * a;
          char b[size],temp[size];
          bool rcdcs=(bcd|bcs);
          for(i=0;i<size;i++) (int)c[i]=0;
          int s=0;
          cin >> c;
          if(sent){k=0;mi++;}
          end=strcmp(c,"zzz")==0;
          bcd=(strcmp(c,"If")==0|strcmp(c,"if")==0); // bool condition = true | false
          bcs=(strcmp(c,"Then")==0|strcmp(c,"then")==0); // bool consequence = true | false
          bre=strcmp(c,"because")==0; // bool reason = true | false
          bso=(strcmp(c,"some")==0|strcmp(c,"Some")==0);
          bal=(strcmp(c,"all")==0|strcmp(c,"All")==0);
          kso=ksome==1;
          kal=kall==1;
          mod=strcmp(c,"have")==0; // bool modifier = true | false
          kar=strcmp(c,"are")==0;
          bis=strcmp(c,"is")==0;
          bnt=(strcmp(c,"Not")==0|strcmp(c,"not")==0);
          if(!(end|bre|bcd|bcs|bso|kar|bal|bis|mod))
          {
              strcat(memory[mi].a," ");
              strcat(memory[mi].a,c);
          }
          else
          {
              kis=0;
              mi++;
          }
          if(end){ k=-1; }
          if(bre){ k=0; re++; if(kso)so++; if(kal)al++; ksome=kall=0;             cin >> c; if(rcdcs) k=6; else{strcat(claimreason[re].a," ");strcat(claimreason[re].a,memory[mi-1].a);}}
          if(bcd){ k=1; it++; if(kso)so++; if(kal)al++; ksome=kall=0;             cin >> c; }
          if(bcs){ k=2;       if(kso)so++; if(kal)al++; ksome=kall=0;             cin >> c; }
          if(bso){ k=3; so++;              if(kal)al++; ksome=1; kall=0;          cin >> c; }
          if(kar){ k=4; if(kso)strcat(some[so].m,c); if(kal)strcat(all[al].m,c);  cin >> c; }
          if(bal){ k=5; al++; if(kso)so++;              ksome=0; kall=1;          cin >> c; }
          if(mod){ k=4; al++; if(kso)so++;              ksome=0; kall=1;          cin >> c; strcat(all[al].a,memory[mi-1].a);}
          if(bnt){ k=7; no++; if(kso)so++; if(kal)al++; ksome=kall=0;             cin >> c; }
          if(bis){ kis=1; is=1; cin >> c; if(strcmp(c,"a")==0||strcmp(c,"an")==0){ al++; strcat(all[al].m,"are"); strcat(all[al].a,memory[mi-1].a); ksome=0; kall=1; k=4; cin >> c;}}
          a = strtok (c,".,.!?");
          if(strcspn (c,".")<strlen(c)) sent=true;
          if(is==1)
          {
              strcat(temp," is");
              is=0;
          }    
          strcat(b," ");
          strcat(b,a);
          strcat(temp,b);
          if(kis==1&&k==1)
          {
            strcat(ifthen[it].i1,b);
          }
          if(kis==1&&k==2)
          {
            strcat(ifthen[it].i2,b);
          }
          if(k==0)
          {
            strcat(claimreason[re].b,temp);
          }
          if(k==1)
          {
            strcat(ifthen[it].a,temp);
          }
          if(k==2)
          {
            strcat(ifthen[it].b,temp);
          }
          if(k==3)
          {
            strcat(some[so].a,temp);
          }    
          if(k==4)
          {
              if(ksome==1)
              {
                strcat(some[so].b,temp);
              }    
              else if(kall==1)
              {
                strcat(all[al].b,temp);
              }
          }    
          if(k==5)
          {
            strcat(all[al].a,temp);
          }
          if(k==6)
          {
            strcat(ifthen[it].c," ");
            strcat(ifthen[it].c,memory[mi-1].a);
          }    
          if(k==7)
          {
            strcat(nOt[no].w,b);
          }
          strcpy(a,"");
          strcpy(b,"");
          strcpy(temp,"");
      }   while(!end);
      for(i=0;i<=re|i<=it;i++)
      {
       if(strlen(ifthen[i].a)>0){ cout<<"Condition "<<i+1<<":  "<<ifthen[i].a<<endl; }
       if(strlen(ifthen[i].b)>0){ cout<<"Consequence "<<i+1<<":  "<<ifthen[i].b<<endl; }
       if(strlen(ifthen[i].c)>0){ cout<<"Reason "<<i+1<<":  "<<ifthen[i].c<<endl; }
       if(strlen(claimreason[i].a)>0){ cout<<"Claim "<<i+1<<":  "<<claimreason[i].a<<endl; }
       if(strlen(claimreason[i].b)>0){ cout<<"Reason "<<i+1<<":  "<<claimreason[i].b<<endl; }
      }
      for(i=0;i<=so|i<=al|i<=it|i<=no;i++)
      {
          for(j=0;j<=so|j<=al|j<=it|j<=no;j++)
          {
              bool sacmp=strcmp(some[i].a,all[j].a)==0&&strcmp(some[i].b,"")!=0;
              bool aacmp=strcmp(all[i].b,all[j].a)==0&&strcmp(all[i].b,"")!=0;
              bool itcmp=strcmp(ifthen[i].b,ifthen[j].a)==0&&strcmp(ifthen[i].b,"")!=0;
              bool itncmp=strcmp(ifthen[i].a,nOt[j].w)==0&&strcmp(ifthen[i].a,"")!=0;
              bool itincmp=strcmp(ifthen[i].i1,nOt[j].w)==0&&strcmp(ifthen[i].i1,"")!=0;/*
              cout<<"some[i].a = "<<some[i].a<<endl;
              cout<<"some[i].b = "<<some[i].b<<endl;
              cout<<"all[i].a = "<<all[i].a<<endl;
              cout<<"all[i].b = "<<all[i].b<<endl;
              cout<<"ifthen[i].a = "<<ifthen[i].a<<endl;
              cout<<"ifthen[i].b = "<<ifthen[i].b<<endl;
              cout<<"ifthen[i].i1 = "<<ifthen[i].i1<<endl;
              cout<<"ifthen[i].i2 = "<<ifthen[i].i2<<endl;
              cout<<"nOt[j].w = "<<nOt[j].w<<endl;*/
              if(sacmp)
              {
                  cout<<"All"<<some[i].b<<" are"<<all[j].b<<"."<<endl;
                  al++;
                  strcpy(all[al].a,"");
                  strcpy(all[al].b,"");
                  strcat(all[al].a,some[i].b);
                  strcat(all[al].b,all[j].b);
              }    
              if(aacmp)
              {
                  cout<<"All"<<all[i].a<<" are"<<all[j].b<<"."<<endl;             
                  al++;
                  strcpy(all[al].a,"");
                  strcpy(all[al].b,"");
                  strcat(all[al].a,all[i].a);
                  strcat(all[al].b,all[j].b);
              }    
              if(itcmp)
              {
                  cout<<"If"<<ifthen[i].a<<" then"<<ifthen[j].b<<"."<<endl;             
                  it++;
                  strcpy(ifthen[it].a,"");
                  strcpy(ifthen[it].b,"");
                  strcat(ifthen[it].a,ifthen[i].a);
                  strcat(ifthen[it].b,ifthen[j].b);
              }
              if(itncmp)
              {
                  cout<<"Not"<<ifthen[i].b<<"."<<endl;             
                  no++;
                  strcpy(nOt[no].w,"");
                  strcat(nOt[no].w,ifthen[i].b);
              }
              if(itincmp)
              {
                  no++;
                  strcpy(nOt[no].w,"");
                  if(strlen(ifthen[i].i2)>0)
                  {
                      cout<<"Not"<<ifthen[i].i2<<"."<<endl;
                      strcat(nOt[no].w,ifthen[i].i2);
                  }    
                  else
                  {
                      cout<<"The following statement is "<<ifthen[i].b<<"."<<endl;
                      strcat(nOt[no].w,ifthen[i].b);
                  }
              }
          }    
      }
      cout<<"Would you like try another sentence (say yes if you agree)?... ";
      cin>>c;
  }   while(strcmp(c,"yes")==0);
  system("PAUSE");
  return 0;
}
 

Attachments

  • kmarinas86artificialintelligence.gif
    kmarinas86artificialintelligence.gif
    15.9 KB · Views: 718
Last edited:
Technology news on Phys.org
Nice Job!
I haven't gone through your code, but the output is pretty good. For further development, you may like to try to get your hands on the following papers,
1] Newell A., Shaw J.C., Simon H.A., (1959). Report on a general problem-solving program. Proceedings of the International Conference on Information Processing. pp. 256-264.
2] Newell, A. (1963). A guide to the general problem-solver program GPS-2-2. RAND Corporation, Santa Monica, California. Technical Report No. RM-3337-PR.
3] Ernst, G.W. and Newell, A. (1969). GPS: a case study in generality and problem solving. Academic Press.

For the time being, you may like to read this article,
http://www.cog.jhu.edu/faculty/smol...tions Readings PDFs/Newell&Simon-1963-GPS.pdf

I assume that you are pursuing to write this programs out of sheer fun. In case you are being serious about doing something on this, i would like to warn you that working with syllogisms went to its limit at one point and hence the approach was abandoned at some point after the 1960's.

At the same time, i would like to encourage you to look at statistical inference mechanisms. Especially, combining statistical methods with semantic constraints is a hot topic in research.

Anyways, good job! :)

-- AI
 
Last edited by a moderator:
I strongly recommend that you learn to use some kind of a lexer/parser, then separate the "computational" part of your code from the lexer/parser.

I'd look into ANTLR and StringTemplate. You can use these tools to generate lexers and parsers based on simple (but powerful) grammars. You can then just walk the resulting syntax tree to perform your computations, all in one simple, abstract block of code. The entire "meat" of the code you provided here is probably only a few dozen lines; the rest is all parsing.

Just my $0.02. Learning ANTLR (or related tools like flex and bison) would be very beneficial for any programmer. In the "real world," few people write their own parsers unless there's a very strong reason they must.

- Warren
 

Similar threads

Replies
12
Views
3K
  • · Replies 75 ·
3
Replies
75
Views
7K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 3 ·
Replies
3
Views
4K
  • · Replies 89 ·
3
Replies
89
Views
6K
Replies
3
Views
3K
  • · Replies 2 ·
Replies
2
Views
2K
Replies
10
Views
2K
  • · Replies 33 ·
2
Replies
33
Views
7K
  • · Replies 29 ·
Replies
29
Views
4K