• 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语言,觉得那个语言蛮不错的。希望到时能有所成就,再在博客上写点东西,到时希望大家支持哦,呵呵......

  • 相关阅读:
    简单的MVC小应用
    jsp四大指令元素,三大脚本元素,八大动作元素
    servlet session管理的四种方式 --隐藏表单
    servlet session管理的四种方式--一 url重写
    创建servlet三种方式(韩顺平老师课程)
    python函数
    tcpprobe ——监听TCP信息的内核模块
    Popen的方法
    Python中执行系统命令常见的几种方法
    > /dev/null 2>&1 含义
  • 原文地址:https://www.cnblogs.com/carl2380/p/2480819.html
Copyright © 2020-2023  润新知