邏輯式編程還有用嗎?--「三維度」邏輯編程語言的設計(2)

1,邏輯編程語言能作什麼   

    這兩天正在構思這個「三維度」邏輯編程語言的設計系列的下一篇該怎麼寫,正好在上一篇《用寫文章的方式寫程序--「三維度」邏輯編程語言的設計(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,可見,函數式語言是名副其實的「高薪語言」,還能說函數式語言「只能在簡單或靜態環境」,而不能運用在複雜或動態環境的環境嗎?沒有哪一個老闆會在那種「簡單或者靜態環境」的軟件開發項目中給程序員高新吧?迴歸主題,本篇文章是討論邏輯編程語言的,上面說這麼多,就是要告訴你們,邏輯式編程的重要性,它尤爲適合處理複雜的認知問題,解決複雜的業務問題,一樣可以構建工業級的商業軟件編程語言

2,從一個遊戲認識邏輯編程

    前面說了邏輯編程語言的重要性,簡單介紹了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. 有一個姑娘很漂亮,美如貂蟬;
  2. 有一個小夥年輕有爲,名叫張三;
  3. 張三是一個打工仔;
  4. 貂蟬是張三的妻子;
  5. 張三是貂蟬的丈夫;
  6. 貂蟬尚未生孩子;
  7. 丈夫能夠努力工做打工賺錢;
  8. 妻子過了35歲生孩子就晚了;
  9. 丈夫要孩子不能超過60歲,且存款不能小於1萬元;
  10. 張三努力打工。
  11. 張三和貂蟬如今能夠生孩子了嗎?

   在這個故事中,第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() ,可是他們兩我的真的能生孩子嗎?這裏不得不提出一個嚴肅而認真的問題:生孩子不是小事,它要看狀況。這個「看狀況」講的就是一個環境、時機、條件等等,好比是否符合我國有特點的「計劃生育制度」,是否符合優生優育,物質條件是否足夠,心理有沒有作好準備。。。在本文中,我將這種「看狀況」有一個正式的詞語來表達--場景,在當前的遊戲人生故事中,這裏的問題就是「生育場景」中的問題。

3,「三維度」邏輯編程

    在「三維度」理論中,場景就是有角色參與的,角色在其中進行交互活動的環境。場景由於有角色參與纔有意義,角色由於有場景的存在才能發揮角色的行爲。在角色與場景的交互過程當中,角色和場景的改變可能會誕生新的角色、產生新的場景,而這種變化能夠體如今時間維度上。因此三維度理論中的角色、場景和時間是相互影響、緊密相關、不可或缺的關係,具體內容能夠參考我以前的文章《業務分析三維度(場景+角色+時 間)之程序員坐禪論道》。用三維度理論能夠能夠很好的描述咱們這個遊戲人生故事中的生孩子問題,它的角色維度正好能夠描述邏輯編程語言中「一階謂詞」,好比上面代碼中的Worker、Wife、Husband類,這些「謂詞」描述了對象的特徵,或者對象之間的關係,能夠表達一些「事實」之間的關係,實現邏輯編程語言中的「謂詞演算」;它的場景維度能夠用來構建一組相關的事實,而且表達這些事實相互之間的一套規則,也就是場景規則。場景更像一個劇本中的槽,這是專家系統中有關知識表達的高級話題,在此先不予討論。這裏的角色維度對應的是謂詞邏輯表示法,而場景維度更像是一套產生式規則系統,劇本包含了時間維度下的不一樣場景,所以三維度理論也是一套描述(表示)複雜業務知識的理論。有關謂詞邏輯、產生式規則和劇本框架,請參考《知識圖譜學習筆記(三)——知識表示方法》。

    因此,要解決當前遊戲中男女主角是否能生孩子的問題,咱們的程序還必須引出「場景」對象,定義一個生育場景,它包括一套有關生孩子的規則,這個規則不一樣於丈夫、妻子角色自身的規則,前者是社會性、法律法規性質的約束;後者是生理性、心理性的約束。好比我國以前的計劃生育制度,要求一對夫妻只能生育一個孩子;如今的制度是能夠生兩個。所以,場景規則隨着時間的推移也能夠是能夠改變的,脫離時間維度去看場景問題是不對的,一樣脫離時間維度去看角色問題也不對,好比咱們的故事中男女主角都會隨着時間的變化而增大年齡,有可能過了最佳生育年齡。這裏能夠總結出,角色對象有角色固有的規則,場景對象也有場景的規則。

    假定咱們已經定義了一個生育場景對象,咱們就能夠將男女角色放入生育場景,開始咱們故事的排練了,而這個就是咱們故事要寫的劇本。爲了簡化劇本,下面的代碼再也不重複前面已經定義的事實,直接簡化爲下面的過程:

  1. 進入場景。
  2. 生孩子?
  3. 努力工做賺錢。
  4. 生孩子?
  5. 結束場景。

對應的代碼以下:

 

 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框架「企業級」應用數據架構實戰》一書中事先看到答案。

4,本篇小節

    本篇先討論了什麼是邏輯編程,以及邏輯編程的重要性,而後用一個實例介紹了Prolog這門邏輯編程語言。而後思考邏輯編程的特色,它和咱們的「三維度」理論有着自然的契合度。運用三維度理論,咱們能夠很容易的用一種非邏輯編程語言--C#來實現邏輯編程的範式,這樣咱們就能結合邏輯編程的有點以及.NET平臺語言強大的功能,從而輕鬆的構建一個新的邏輯編程語言,儘管這隻能稱之爲一種DSL,但它也能爲一種新的邏輯編程語言的設計提供一個可實現的參考方案。

    在下一篇,咱們將討論這個「三維度」邏輯編程語言的設計細節,已經購買了個人書的朋友能夠先一睹爲快。你們有什麼問題能夠回帖留言,也方便爲我下一篇具體寫做內容提供思路,謝謝你們的支持。

相關文章
相關標籤/搜索