勇闖新世界︰ 《 pyDatalog 》 導引《一》

《 Simply Logical
Intelligent Reasoning by Example 》

之第一部份起頭處, Peter Flach 開宗明義的講︰

Logic and Logic Programming

Logic Programming is the name of a programming paradigm which was developed in the 70s. Rather than viewing a computer program as a step-by-step description of an algorithm, the program is conceived as a logical theory, and a procedure call is viewed as a theorem of which the truth needs to be established. Thus, executing a program means searching for a proof. In traditional (imperative) programming languages, the program is a procedural specification of how a problem needs to be solved. In contrast, a logic program concentrates on a declarative specification of what the problem is. Readers familiar with imperative programming will find that Logic Programming requires quite a different way of thinking. Indeed, their knowledge of the imperative paradigm will be partly incompatible with the logic paradigm.

This is certainly true with regard to the concept of a program variable. In imperative languages, a variable is a name for a memory location which can store data of certain types. While the contents of the location may vary over time, the variable always points to the
same location. In fact, the term ‘variable’ is a bit of a misnomer here, since it refers to a value that is well-defined at every moment. In contrast, a variable in a logic program is a variable in the mathematical sense, i.e. a placeholder that can take on any value. In this respect, Logic Programming is therefore much closer to mathematical intuition than imperative programming.

Imperative programming and Logic Programming also differ with respect to the machine model they assume. A machine model is an abstraction of the computer on which programs are executed. The imperative paradigm assumes a dynamic, state-based machine model, where the state of the computer is given by the contents of its memory. The effect of a program statement is a transition from one state to another. Logic Programming does not assume such a dynamic machine model. Computer plus program represent a certain amount
of knowledge about the world, which is used to answer queries.

,指出『邏輯編程』和『 Von Neumann 程式語言』──

摘自《 CPU 機器語言的『解譯器』》︰

事實上 Von Neumann 的計算機架構,對於電腦程式語言的發展,有著極為深遠的影響,產生了現在叫做 Von Neumann 程式語言,與Von Neumann 的計算機架構,同形 isomorphism 同構

program variables ↔ computer storage cells
程式變數 對映  計算機的儲存單元

control statements ↔ computer test-and-jump instructions
控制陳述  計算機的『測試.跳至』指令

assignment statements ↔ fetching, storing instructions
賦值陳述  計算機的取得、儲存指令

expressions ↔ memory reference and arithmetic instructions.
表達式  記憶體參照和算術指令

── 之『觀點』有極大的不同。通常這造成了學過一般程式語言的人『理解』上的困難。也可以說『邏輯編程』之『推導歸結』得到『證明』的想法遠離『圖靈機』的『狀態轉移』到達『接受』狀態 。反倒是比較接近『 λ運算』與『 Thue 字串改寫系統』抽象建構。讀者可以試著參考讀讀那些文章, 看看能否將『思考』方式的

Logic Programming requires quite a different way of thinking. Indeed, their knowledge of the imperative paradigm will be partly incompatible with the logic paradigm.

『不相容性』鎔鑄成整體思維之『結晶』,嫻熟用於解決各式各樣的『問題』!

也許『學習』到了一定的時候,或早或遲人們需要想想『學習方法 』,經由對自己的了解,找到『事半功倍』的有效作法。雖說人人都是獨特的,然而在『學習』上確實有很多類似的『難處』。比方說一般寫程式的思維,有所謂『從上往下』 Top-Down 以及『由底向頂』 Button-Up 思路取向不同。一者類似『歐式幾何』,從公理公設出發,逐步推演定理定律,邏輯清楚明白。然而一旦要自己去證明 □□ 定理時,有時總覺的無處下手。這是因為由『公理』通往『定理』的『推導歸結』之道路遙遠,常常看不出 ○□ 兩個『概念 』間竟然有如此的『聯繫』。另一彷彿『學會做菜』,由觀察親朋做菜開始,知道什麼菜要怎麼洗?怎麼切?用什麼方法調理?久而久之,學會了一道二道三道很多很多的菜的作法。也可以講,這樣的『學法』知道了許多『如何作』 Know-How ,很少思考『為什麼 』 Know-Why 這麼作,也很少形成一般『這一類』 Know-What 的菜,多半這樣作的『通則』。我們將要如何回答別人,自己『想都沒想過』,這菜『卻得這麼作』的『問題』?或許異地嫁娶之人,更能體會,這種『不同』就是『不同』的意思。

既然打算『勇闖』,並非『暴虎馮河』,而是『有勇有謀』,想那『新世界』的『智能機器』,難到不會『自我學習』?何不就假借此時『野人獻曝』,用著談『學習之法』來學此法!體會『遞迴』之『遞迴』也許正是『邏輯』的『原點』??『方法』的『方法』或者恰是『智慧』之『菩提』!!

就讓我們效法『科學家』的精神,用著探索『大自然』的方法,弄明白他到底如何研究『未知』。假設已知『 pyDatalog 』 源於

Datalog ,也知道一般『邏輯編程』是什麼

Logic programming ,還知道關鍵句式是『霍恩子句

Horn clause

。同時據該作者講︰

pyDatalog is derived from previous work by John D. Ramsdell

,那麼在閱讀

Datalog User Manual

5 Syntax

In Datalog input, whitespace characters are ignored except when they separate adjacent tokens or when they occur in strings. Comments are also considered to be whitespace. The character ‘%’ introduces a comment, which extends to the next line break. Comments do not occur inside strings.

The characters in Datalog input are collected into tokens according to the rules that follow. There are four classes of tokens: punctuations, variables, identifiers, and strings.

The punctuation tokens are: ‘(’, ‘,’, ‘)’, ‘=’, ‘:-’, ‘.’, ‘~’, ‘?’, and ‘”’.

A variable is a sequence of Latin capital and small letters, digits, and the underscore character. A variable must begin with a Latin capital letter.

An identifier is a sequence of printing characters that does not contain any of the following characters: ‘(’, ‘,’, ‘)’, ‘=’, ‘:’, ‘.’, ‘~’, ‘?’, ‘”’, ‘%’, and space. An identifier must not begin with a Latin capital letter. Note that the characters that start punctuation are forbidden in identifiers, but the hyphen character is allowed.

A string is a sequence of characters enclosed in double quotes. Characters other than double quote, newline, and backslash can be directly included in a string. The remaining characters can be specified using escape characters, ‘\”’, ‘\n’, and ‘\\’ respectively.

Other escape characters can be used to improve the readability of the input. If a string is too long to fit conveniently on one line, all but the final line containing the string can be ended with a backslash character, and each backslash newline pair is ignored. The character escape codes from the C programming language are allowed—‘\a’, ‘\b’, ‘\f’, ‘\n’, ‘\r’, ‘\t’, ‘\v’, ‘\’’, and ‘\?’. The numeric escape codes consist of one, two, or three octal digits. Thus the ASCII character newline is ‘\012’, and zero is ‘\000’. A printed Datalog string is also a string constant in C.

5.1 Literals

A literal, is a predicate symbol followed by an optional parenthesized list of comma separated terms. A predicate symbol is either an identifier or a string. A term is either a variable or a constant. As with predicate symbols, a constant is either an identifier or a string.

The following are literals:

parent(john, douglas)
zero-arity-literal
aBcD(-0, “\n\377”)
“=”(3,3)
“”(-0-0-0,&&&,***,”\0”)

5.2 Clauses

A clause is a head literal followed by an optional body. A body is a comma separated list of literals. A clause without a body is called a fact, and a rule when it has one. The punctuation ‘:-’ separates the head of a rule from its body. A clause is safe if every variable in its head occurs in some literal in its body.

The following are safe clauses:

parent(john, douglas)
ancestor(A, B) :-
parent(A, B)
ancestor(A, B) :-
parent(A, C),
ancestor(C, B)

5.3 Programs

A Datalog reader consumes a Datalog program. A program is a sequence of zero or more statements, followed by an optional query. A statement is an assertion or a retraction. An assertion is a clause followed by a period, and it adds the clause to the database if it is safe. A retraction is a clause followed by a tilde, and it removes the clause from the database. A query is a literal followed by a question mark. The effect of reading a Datalog program is to modify the database as directed by its statements, and then to return the literal designated as the query. If no query is specified, a reader returns a literal know to have no answers.

The following is a program:

edge(a, b). edge(b, c). edge(c, d). edge(d, a).
path(X, Y) :- edge(X, Y).
path(X, Y) :- edge(X, Z), path(Z, Y).
path(X, Y)?

,同時參考

Datalog tutorial

pyDatalog is a powerful language with very few syntactic elements, mostly coming from Python : this makes it easy to learn ! In this tutorial, we’ll review:

  • Variables and expressions
  • Loops
  • Logic Functions and dictionaries
  • Aggregate functions
  • Literals and sets
  • Tree, graphs and recursive algorithms
  • 8-queen problem

We’ll see that pyDatalog statements are declarative : they describe the result we want, leaving to the computer the task of finding the appropriate solutions. We’ll start with trivial problems to show the basics of the language, and progressively address more complex problems, to show how simply they can be expressed. We’ll finish with an efficient solution to the 8-queen problem.

……

,以及了解安裝方法

#
sudo pip-3.2 install pyDatalog
sudo pip-3.2 install sqlalchemy 
#

後,我們是否就已學會且能詮釋

pi@raspberrypi ~ $ python3
Python 3.2.3 (default, Mar  1 2013, 11:53:50) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from pyDatalog import pyDatalog
>>> pyDatalog.create_terms('X單位, Y單位, Z單位, V數值, 單位轉換, 重量轉換')
>>> 單位轉換['公斤', '公克'] = 1000
>>> 單位轉換['台斤', '公克'] = 600
>>> 單位轉換['市斤', '公克'] = 500
>>> 單位轉換['英磅', '公克'] = 453.59237
>>> 單位轉換[X單位, Y單位] = 單位轉換[X單位, Z單位] * 單位轉換[Z單位, Y單位]
>>> 單位轉換[X單位, Y單位] = 1 / 單位轉換[Y單位, X單位]
>>> print(單位轉換['公斤', '台斤'] == V數值)
V數值               
------------------
1.6666666666666667
>>> print(單位轉換['英磅', '台斤'] == V數值)
V數值               
------------------
0.7559872833333334
>>> 單位轉換['台斤', '台兩'] = 16
>>> 重量轉換[V數值, X單位, Y單位] = V數值 * 單位轉換[X單位, Y單位]
>>> print(重量轉換[1, '公斤', '台兩'] == V數值)
V數值               
------------------
26.666666666666668
>>> 

這個程式的『意指』的呢?