VC++与Prolog混合编程

http://hi.baidu.com/%B2%BD%D0%D0%D6%AE%C2%C3/blog/item/c3485eca9e397af753664fe5.html

  先申明下,我也是菜鸟,所有以下介绍中出现有问题的地方,不要怪小弟,我们“机器人足球”老师(选修课)让我们做的一个程序,用到了Proglog语言,并且要求用VC++做界面,将信息存在Proglog语言中。所有我只是知道一点点东西,只具有刚好完成作业的“能力”。

               先介绍下Proglog语言,我用的软件是Amzi! Prolog ,这个软件只有3M多,如果要下的话,到http://download.pchome.net/development/linetools/detail-10087.html进行下载。与其说这是一个开发Prolog语言的软件,不如说它提供的是一个库,这个库里有VC++与Prolog语言混合编程所需要的文件,这些文件也是VC++里面要用到的,由于在VC++库中没有,所有首先要将这些文件移到你所写程序的目录下,然后再加入到你所写程序的工程中。(所说的文件有amzi.h,amzi.lib,amzi.dll)

             Prolog语言是“逻辑设计语言”,可以说是人工智能里不可或缺的一门语言,我知道最基础的一点点东西,我们学离散数学时,学到了谓词工式那一章,比如说R(x),表示的含义是任意的,一般程序是不管具体语义的,它只关心公式本身,而具体语义是编程人员需要在意的,而在Prolog语言中,数据是不用事先定义的,小写的“标识”是常量,大写的“标识符”是未知量,比如说有下面一段程序:                    

               animal(dog):-can(noise_far),is(feed_animal).

              animal(X):-can(noise_far),is(feed_animal).

              上面一短程序中,只有X是未知的,其中“:-”表示“如果”的意思,“,”表示“且”,“.”表示一个规则完了,上面的意思翻译成中文就是:

               有一个哺乳动物,并且能够嗅到很远,那么它就是狗。

                能够嗅到很远的哺乳动物是什么呢?(X)

                而Prolog语言就是由很多这样的规则和公式组成的一个关系型数据库而以,当用VC++程序进入输入相应需要知道的信息时,将这些信息传入到“Prolog文件(*.xpl)”中,然后这个文件就会将相应的信息返回,在VC++中捕获到这相应信息,再将这些信息经过转化,再将得到的具体信息输出,这就是用VC++与Prolog语言混合编程的思想吧,这跟用数据库编程差不多,主要区别就是:数据库里面有的是数据,而Prolog里面是规则,其实两者实质是一样的。

                现在来介绍一下我的程序:首先来看一下VC++程序与Prolog语言相互传递信息的类,如下所示:

class AnimalMsg : public CLogicServer
{
public:
AnimalMsg(void);
~AnimalMsg(void);
public:
void AddAnimalMsg(CString msg);
CString GetAnimal(void);
private:
void error(CLSException & e);
};

AnimalMsg::AnimalMsg(void)//初始化类,并加载相应的prolog文件(animal.xpl)
{
try
{
   Init("");
   Load("animal.xpl");
}
catch(CLSException &e)//如果出现异常
{
   error(e);
}

/*向Prolog中输入“问题”,这个问题就是给的条件,然后Prolog会跟据这些东西来分析,提供答案,但是这个问题还没有给完整,比如在Prolog文件中有以下信息:

animal(dog):-can(noise_far).           %能够嗅很远的是狗

is(creature):-can(noise_far).            %能够嗅很远的是生物

我们先不管这个例子所表示的具体含义,在下面的函数里只能提供右部分的信息,但是Prolog是不知道到底是返回dog还是creature,也就是说程序中还要用到另一个函数,提供右部的“谓词”公式,也就是在返回结果GetAnimal(void)中应用到了*/

void AnimalMsg::AddAnimalMsg(CString msg)
{
char *pBuf;

int size = msg.GetLength();
pBuf = new char[size];

for(int i=0; i<size; ++i) 
{
   pBuf[i] = (char)msg[i];
   pBuf[i+1] = 0;
}

try
{
   AssertzStr(pBuf);
}
catch(CLSException &e)
{
   error(e);
}
}

CString AnimalMsg::GetAnimal(void)
{
char animal[50];
TERM t;
CString str(_T(""));

try
{
   if(ExecStr(&t,"animal(X)"))
   {
    GetArg(t,1,cSTR,animal);
    str.Format("%s",animal);
   }
   else
   {
    str = "不明生物";
   }

}
catch(CLSException &e)
{
   error(e);
}

return str;
}

void AnimalMsg::error(CLSException & e)
{
char buf[500];
    e.GetMsg(buf, 500);
CString str;
str.Format("%s",buf);
AfxMessageBox(str);
throw("AnimalMsg error!");
}

            由于Prolog里面是不能含有中文的,而界面上都是对应的中文信息,所以最好有两个数组,将相应的信息对应起来,下标应该是一样的,这样就比较方便了,不过我的程序是这样处理的,如下所示:

typedef struct tagAnimal//返回的结果也是英语,所以这个是用来将英语转化成中文的
{
CString name;//中文名字
CString id;// 对应的ID,也就是“英语”表示的
tagAnimal(CString na = _T(""), CString i = _T(""))
   : name(na), id(i){}
} Animal;

typedef int TYPE;
typedef struct tagCharacter//特点的定义
{  
TYPE type;//type=0,is(X);type=1,have(X);type=2,can(X).
CString msg;//属性
CString id;//属性id,就是“英语”表示的
tagCharacter(TYPE ty = 0, CString ms = _T(""), CString i = _T(""))
   : type(ty), msg(ms), id(i){}
} Character;

            然后再将信息输进这里面,我用的是向量:

///初始化特征值
m_character.push_back(Character(0,"01.哺乳动物","feed_animal"));
m_character.push_back(Character(0,"02.食肉动物","eat_animal"));
m_character.push_back(Character(0,"03.有蹄动物","hoof_animal"));
m_character.push_back(Character(1,"04.有奶","milk"));
m_character.push_back(Character(1,"05.有毛发","hair"));
m_character.push_back(Character(1,"06.有羽毛","feather"));
m_character.push_back(Character(1,"07.有爪","paw"));
m_character.push_back(Character(1,"08.有犬齿","tooth"));
m_character.push_back(Character(1,"09.有蹄","hoof"));
m_character.push_back(Character(1,"10.有黄褐色条纹","tawny"));
m_character.push_back(Character(1,"11.有黑色条纹","blackstripe"));
m_character.push_back(Character(1,"12.有黑色斑点","blackstain"));
m_character.push_back(Character(1,"13.有长腿","long_leg"));
m_character.push_back(Character(1,"14.有脖子","long_neck"));
m_character.push_back(Character(1,"15.有暗斑点","dimstain"));
m_character.push_back(Character(1,"16.有白色条纹","white"));
m_character.push_back(Character(2,"17.能目盯前方","see_ahead"));
m_character.push_back(Character(2,"18.能吃肉","eat_meat"));
m_character.push_back(Character(2,"19.能生蛋","egg"));
m_character.push_back(Character(2,"20.能飞","fly"));
///初始化,有那些动物
m_animal.push_back(Animal("无法推测","nul"));
m_animal.push_back(Animal("鸟","bird"));
m_animal.push_back(Animal("老虎","tiger"));
m_animal.push_back(Animal("金钱豹","money_panther"));
m_animal.push_back(Animal("长颈鹿","giraffe"));
m_animal.push_back(Animal("斑马","zebra"));

/*以下是程序中的分析函数,过程很简单,就没什么好说的,呵呵

void CAnimal分类Dlg::Analyse(void)
{
pMesg = new AnimalMsg();//重新建,防止信息重复
CString msg;
for(int i=0; i<m_ctrlAlready.GetCount(); ++i)
{
   m_ctrlAlready.GetText(i,msg);
   for(vector<Character>::iterator iter=m_character.begin(); 
    iter!=m_character.end(); ++iter)
   {
    if(iter->msg == msg)
    {
     switch(iter->type)
     {
     case 0:msg = "is(" + iter->id + ")";break;
     case 1:msg = "have(" + iter->id + ")";break;
     case 2:msg = "can(" + iter->id + ")";break;
     }
     pMesg->AddAnimalMsg(msg);
     break;
    }
   }
}

vector<Animal>::iterator iter;
for(iter=m_animal.begin(); iter!=m_animal.end(); ++iter)
    if(iter->id == pMesg->GetAnimal())
     break;
if(iter == m_animal.end())
   GetDlgItem(IDC_RESULT)->SetWindowTextA("无法推测");
else
   GetDlgItem(IDC_RESULT)->SetWindowTextA(iter->name);
}

           本人自从这个例子里面略用了下Prolog,觉得它与我原来接触到的C/C++/C#/Java等是很不相同的,等把这学期的学习搞定后,花点时间再好好学下Prolog语言,觉得那个语言蛮不错的。希望到时能有所成就,再在博客上写点东西,到时希望大家支持哦,呵呵......

转载于:https://www.cnblogs.com/carl2380/archive/2012/05/03/2480819.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值