这两天正在构思这个“三维度”逻辑编程语言的设计系列的下一篇该怎么写,正好在上一篇《用写文章的方式写程序--“三维度”逻辑编程语言的设计(1)》有位叫作 dwcz 的朋友回帖说:html
“没啥特色。新出的语言都快实现的功能,还在这里进行理论构想。逻辑式编程基本被否认了,和函数式有一样问题--只能在简单或静态环境,在复杂或动态环境,形成的问题比要解决的问题还多。”程序员
不知道这位朋友具体是出于什么缘由这么认为的,我认为一个东西不流行不表明它是失败的、被否认的事物。逻辑编程语言这几年的确不多出如今编程社区的讨论中,更看不到有关职位的招聘信息,本着“用脚投票”的原则,认为逻辑编程语言没什么用,已经被否认、被淘汰的观点就有市场了,可是这种观点是不正确的,流行的东西不必定是好东西,好比流感;不流行的东西只不过很小众,只要它存在就有它的一小片天地。逻辑编程语言的确很小众,它有它特殊的应用领域, dwcz 偏偏说反了,逻辑编程语言主要的用武之地就是复杂和动态的环境,这个能够从逻辑编程语言Visual Prolog的官网介绍看到:编程
https://www.visual-prolog.com/default-chinese.htm
使用Visual Prolog能够构建工业级的商用程序,尤为适合处理复杂的认知问题。
Prolog语言开发中心业已证明,如下项目中的先进资源调度和决策支持系统彻底是用Visual Prolog编写的:架构
员工规划 机场决策支持 航空公司决策支持 车间调度 基于语音的解决方案 CrewWatch Ra
上面一段介绍的详细内容请点击上面的连接了解。而函数式语言跟逻辑编程语言有一样问题这个说法更不对,函数式语言的鼻祖LISP至今还在,基于JVM的LISP方言Clojure还能经常出如今招聘信息中,还有比Common LISP更为简单的方言Scheme,它有一个完善IDE环境的DrRacket实现,还有编译和运行速度比C还快的Chez Scheme,详情能够看看知乎对此的讨论,也能够看看王垠写的这篇《揭秘Chez Scheme》(王垠本身的博客已经加密,这里贴的是转载的文章)。我使用Chez Scheme编写了一个新冠病毒感染风险监测程序,能够点击我这篇文章《Scheme语言实例入门--怎样写一个“新型冠状病毒感染风险检测程序” 》了解和下载运行这个Scheme程序。此外,经常使用的函数式语言还有scala, erlang, F#, Haskell等,说到.NET就不能不提到F#,.NET 5.0将伴随C#9.0同步发布最新的F# 5.0,可见F#在软微开发语言中的重要地位。奇怪的是,F#在国内鲜有使用,而在国外被称为薪水最高的编程语言,以下图2019编程语言薪资排行榜。框架
从上面的编程语言排行榜上能够看到,Top 3的语言有两名都是函数式语言,Erlang都能排名No.9,可见,函数式语言是名副其实的“高薪语言”,还能说函数式语言“只能在简单或静态环境”,而不能运用在复杂或动态环境的环境吗?没有哪一个老板会在那种“简单或者静态环境”的软件开发项目中给程序员高新吧?回归主题,本篇文章是讨论逻辑编程语言的,上面说这么多,就是要告诉你们,逻辑式编程的重要性,它尤为适合处理复杂的认知问题,解决复杂的业务问题,一样可以构建工业级的商业软件。编程语言
前面说了逻辑编程语言的重要性,简单介绍了Visual Prolog这个逻辑编程语言的用途,但对于习惯了“命令式编程”的程序员来讲可能对于逻辑编程语言仍是没有概念。函数
Prolog 语言是以一阶谓词逻辑演算为原理设计的计算机程序语言,在人工智能的发展 历程中被寄予厚望,曾经被成为“第五代计算机语言”。Prolog 的程序结构就是事实、规则 和问题,它内置一个推理机,经过输入事实,处理规则,求解问题。所以它跟其它程序语言 都不一样,大部分都是命令式的,而 Prolog 是陈述式的,所以不须要告诉 Prolog 程序的执行 顺序便可求解问题。学习
好比看下面的Prolog程序例子:测试
likes(bell, sports). % Bell 喜欢运动 likes(mary, music). % Mary 喜欢音乐 likes(mary, sports). % Mary 喜欢运动 likes(jane, reading). % Jane 喜欢阅读 friend(john, X) :- likes(X, reading), likes(X, music). % 成为 john 的朋友须要喜欢 阅读和音乐 friend(john, X) :- likes(X, sports), likes(X, music). % 成为 john 的朋友须要喜欢 运动和音乐 ?- friend(john, Y). %谁是 john 的朋友?
运行此程序,将得到答案:人工智能
Y= mary
上面的代码第1-第4行,都在说关于“喜欢”什么的事实;第五、第6行,分部定义了成为某我的的朋友的条件,这些条件成为一套规则;最后一行代码是提问。运行Prolog程序后,Prolog内置的“推理机”回溯程序定义的事实,匹配定义的规则,将问题代入这些事实和规则进行消解,最后匹配出答案。(有关这个过程的理解,推荐你们看看《逻辑式编程语言极简实现(使用C#) - 1. 逻辑式编程语言介绍》这篇文章,做者写得诙谐有趣,浅显易懂。)
上面有关Prolog的介绍节选自本人的新书《SOD框架“企业级”应用数据架构实战》【2.1.6 数据、信息和知识】一小节的《第三,什么是知识(Knowledge)?》的内容,已购书的朋友能够看看书中相关内容更多的介绍。
也许上面这个示例程序的运行结果有点”费脑子“,而且这个程序是原生的Prolog程序,不喜欢这种语法风格。不要紧,咱们只要明白Prolog语言就是由事实、规则和问题组成的就好了。下面咱们再经过一个简单一点的“游戏人生”程序来带领你们认识逻辑编程,而且示例代码使用你们熟悉的C#语言来模拟Prolog程序的风格,这样来看逻辑编程就会天然点。编程以前,咱们都会作需求分析,产品经理会给咱们讲一个”用户故事“,在这个游戏中这是两口子决策是否要生孩子的故事。
故事内容:
在这个故事中,第1条-第6条,以及第10条叙述的是故事男女主角已有的“事实”,第7-9条定义的是家庭中有关生孩子的“规则”,第11条提出问题。事实一经发生就不可改变,事实能够是一些对象之间的关系,也能够是对象的行为,好比这里说貂蝉是张三的妻子。规则是一些强制性约束,好比社会性的、生理性的或者法律上的,通常也不能够随意改变。这里定义的规则只有合法成为夫妻才能够生孩子,因此须要先描述男女主角是夫妻关系。固然不结婚也能够生孩子,但这不是本程序考虑的规则。根据事实和规则,咱们就能回答一些问题了,这里的问题是男女主角什么时候可以生孩子。
下面,用C#代码来表示这个故事有关的事实、规则和问题:
Woman diaochan = new Woman() { Name = "貂蝉", Birthday = new DateTime(1990, 1, 2) }; Man zhangsan = new Man() { Name = "张三", Birthday = new DateTime(1988, 3, 5) }; Worker worker1 = new Worker(zhangsan); Wife wife1 = new Wife(diaochan,zhangsan); Husband husband1 = new Husband(zhangsan,diaochan); diaochan.ChildrenCount = 0; diaochan.ActAs<Wife>().Child_bearing(); //生孩子 zhangsan.ActAs<Husband>().Money += zhangsan.ActAs<Worker>().Work(); zhangsan.ActAs<Husband>().Child_rearing(); //生孩子
请看上面这个代码,基本上和咱们的故事“剧本”描述的如出一辙,只不过,生孩子是妻子和丈夫两我的的事情,“一头熟”可生不下孩子,因此对象diaocan和zhangsan均可以调用生孩子的方法Child_rearing() ,可是他们两我的真的能生孩子吗?这里不得不提出一个严肃而认真的问题:生孩子不是小事,它要看状况。这个“看状况”讲的就是一个环境、时机、条件等等,好比是否符合我国有特点的“计划生育制度”,是否符合优生优育,物质条件是否足够,心理有没有作好准备。。。在本文中,我将这种“看状况”有一个正式的词语来表达--场景,在当前的游戏人生故事中,这里的问题就是“生育场景”中的问题。
在“三维度”理论中,场景就是有角色参与的,角色在其中进行交互活动的环境。场景由于有角色参与才有意义,角色由于有场景的存在才能发挥角色的行为。在角色与场景的交互过程当中,角色和场景的改变可能会诞生新的角色、产生新的场景,而这种变化能够体如今时间维度上。因此三维度理论中的角色、场景和时间是相互影响、紧密相关、不可或缺的关系,具体内容能够参考我以前的文章《业务分析三维度(场景+角色+时 间)之程序员坐禅论道》。用三维度理论能够能够很好的描述咱们这个游戏人生故事中的生孩子问题,它的角色维度正好能够描述逻辑编程语言中“一阶谓词”,好比上面代码中的Worker、Wife、Husband类,这些“谓词”描述了对象的特征,或者对象之间的关系,能够表达一些“事实”之间的关系,实现逻辑编程语言中的“谓词演算”;它的场景维度能够用来构建一组相关的事实,而且表达这些事实相互之间的一套规则,也就是场景规则。场景更像一个剧本中的槽,这是专家系统中有关知识表达的高级话题,在此先不予讨论。这里的角色维度对应的是谓词逻辑表示法,而场景维度更像是一套产生式规则系统,剧本包含了时间维度下的不一样场景,所以三维度理论也是一套描述(表示)复杂业务知识的理论。有关谓词逻辑、产生式规则和剧本框架,请参考《知识图谱学习笔记(三)——知识表示方法》。
因此,要解决当前游戏中男女主角是否能生孩子的问题,咱们的程序还必须引出“场景”对象,定义一个生育场景,它包括一套有关生孩子的规则,这个规则不一样于丈夫、妻子角色自身的规则,前者是社会性、法律法规性质的约束;后者是生理性、心理性的约束。好比我国以前的计划生育制度,要求一对夫妻只能生育一个孩子;如今的制度是能够生两个。所以,场景规则随着时间的推移也能够是能够改变的,脱离时间维度去看场景问题是不对的,一样脱离时间维度去看角色问题也不对,好比咱们的故事中男女主角都会随着时间的变化而增大年龄,有可能过了最佳生育年龄。这里能够总结出,角色对象有角色固有的规则,场景对象也有场景的规则。
假定咱们已经定义了一个生育场景对象,咱们就能够将男女角色放入生育场景,开始咱们故事的排练了,而这个就是咱们故事要写的剧本。为了简化剧本,下面的代码再也不重复前面已经定义的事实,直接简化为下面的过程:
对应的代码以下:
Console.WriteLine("-----开启【生育场景】规则测试-------------"); diaochan.ChildrenCount = 0; husband1.Money = 5000; ProcreateContext context = new ProcreateContext(new DateTime(2010, 1, 1), zhangsan, diaochan); context.StartContext(); //场景参与人开始扮演角色 diaochan.ActAs<Wife>().Child_bearing(); zhangsan.ActAs<Husband>().Money += zhangsan.ActAs<Worker>().Work(); zhangsan.ActAs<Husband>().Child_rearing(); //启动规则匹配 Console.WriteLine(); bool rulesFlag = context.MatchRules(); Console.WriteLine("{0} 结果:{1}", context.Name, rulesFlag); Console.Read();
运行这段程序,便可看到张三和貂蝉是否能够生孩子的结果,具体运行结果将在本系列结束后公布,读者也能够从个人《SOD框架“企业级”应用数据架构实战》一书中事先看到答案。
本篇先讨论了什么是逻辑编程,以及逻辑编程的重要性,而后用一个实例介绍了Prolog这门逻辑编程语言。而后思考逻辑编程的特色,它和咱们的“三维度”理论有着自然的契合度。运用三维度理论,咱们能够很容易的用一种非逻辑编程语言--C#来实现逻辑编程的范式,这样咱们就能结合逻辑编程的有点以及.NET平台语言强大的功能,从而轻松的构建一个新的逻辑编程语言,尽管这只能称之为一种DSL,但它也能为一种新的逻辑编程语言的设计提供一个可实现的参考方案。
在下一篇,咱们将讨论这个“三维度”逻辑编程语言的设计细节,已经购买了个人书的朋友能够先一睹为快。你们有什么问题能够回帖留言,也方便为我下一篇具体写做内容提供思路,谢谢你们的支持。