ADP (Another Data Processor) is a programing language that is designed for Web database programing. It is a scripting language and a lightweight programming language in which it is possible to mix SQL easily. It is easy to install.
ADP is base on Prolog. But ADP uses only the backtrack and unification. The syntax is original and likes a another scripting language, supports method call.
This Webpage is made with ADP.
ADP is being developed with the following concepts.
-A multiparadigmlanguage based on logic programming
-A lightweight scripting language
-High affinity for SQL
-Simple and familiar syntax
-Not requires installation of complex procedures
-Decent running speed
-Supporting multi-processors
ADP aims to be a powerful language that helps busy engineers .
String
You can define in C-style string by enclosing the string in double quotes (").
- If you want to put a double quotation in a string, you need to put \" in the string.
- \" and \r and \n, \\ are the same way as C.
You can define in BASIC-style string by enclosing the string in single quotes (').
- If you want to put a single quotation in a string, you need to put '' in the string.
If a string contains new line, it is valid.
Example
"SELECT *
FROM tab "
Variables
A variable name has to start dollar $ sign.
Example
$x
$value
Predicate(Like calling a function)
Predicate is the ADP assessment unit.Write the following.
predicate_name(
argment list)
Example
print("Hello World")
Term
Strings and numbers, variables and predicate are called term.
Goal cluase(Like a function body parts)
Goal cluase has terms separated by commas "," and terminated by a semicolon ";".
Goal clause is evaluated in the description of the order of source files by adp command.
Example
,print("Hello World");
You input the source file above to adp command, then the command 'Hello World' on the screen.
Horn clause(Like a function definition)
Horn clause has a horn head and a goal cluase. The horn head begins from a "+" charactor and has horn_clause_name and argment lists.
+
horn_clause_name(
argment list)
goal_cluase
Example
+horn_name($x,$y),print($x, '=', $y);
Comments
A comment begins from a '#' character and ends to the end of the line.
,printn("Hello World"); # Here is a comment.
Hello Wold
・program code(helloworld.p)
,printn("Hello World.");
・example of the execution
D:\sample>adp helloworld.p
Hello World.
ADP command loads and compiles the program. Then, ADP evaluates goal clauses, executes the program.
This sample, hellowrld.p, is evaluating predicate of 'printn'.
'printn' is one of the embedded predicate, like library, print arguments to the console and line feed.
Example of arithmetic operations
・program code(expression.p)
,$x=10 ,$y=20 ,printn( $x + $y ); # add
,$x=30 ,$y=40 ,printn( $x - $y ); # sub
,$x=50 ,$y=60 ,printn( $x * $y ); # multiply
,$x=70 ,$y=80 ,printn( $x / $y ); # divide
,$x=90 ,$y=100 ,printn( $x % $y ); # modulo
・example of the execution
D:\sample>adp expression.p
30
-10
3000
0
90
ADP supports arithmetic operations.
About executing goal clause (Each term has the executing result)
Each term in a goal clause has the boolean value of the executing result.
If the executing result is true, then ADP will execute next term.
If the executing result is false, then ADP will backtrack, will be described in the next section, instead of execute next term.
・program code(condition.p)
,$x = 10 ,$y = 20 ,$x < $y ,printn("$x is smaller than $y."); # -- (1)
,$x = 10 ,$y = 20 ,$x > $y ,printn("$x is bigger than $y."); # -- (2)
・example of the execution
D:\sample>adp condition.p
$x is smaller than $y.
Predicate 'printn' at (1) is executed, showing '$x is smaller than $y'.
But predicate 'printn' at (2) is not executed, because the expression right before the predicate '$x > $y' returns false. $x is 10, $y is 20, and $x(10) > $y(20) is false.
ADP backtracked after executing the expression.
Horn clauses (1) used by function
You can use a horn clause by function or procedure.
Following example is a horn clause that calculates expression and returns it.
・program code(func.p)
+func($x,$y,$z),$z = $x * $x + $y,!; #--(1)
,func(30,5,$z),print($z);
・example of the execution
D:\sample>adp func.p
905
(1) is the definition of a horn clause. You can write just one line for the definition it. It is simple.
'!' is a cut predicate. See below for further details.
Horn clauses (2) Unification
This section describes unification that is a unique function of ADP(Prolog).
A horn clause is also used like a database. The horn clause search mechanism is called 'Unification'.
Please watch the sample code(unification.p).
・The program code(unification.p)
+capital( 'Japan', 'Tokyo');
+capital( 'United States', 'Washington, D.C.');
+capital( 'United Kingdom', 'London');
+capital( 'Germany', 'Berlin');
+capital( 'Viet Nam', 'Hanoi');
+capital( 'Philippines', 'Manila');
,capital( 'Japan', $c), printn($c);
・The example of the execution
D:\sample>adp unification.p
Tokyo
The Horn clauses 'capital' are database of some countries and capital.
The below Goal clause searches the horn clause that has the first arg is 'Japan'.
,capital( 'Japan', $c)
ADP looks up the follow horn clause in the horn clauses.
+capital('Japan', 'Tokyo');
ADPにはこのようにホーン節と評価中の項(述語)のマッチングを行い、結果マッチするホーン節が見つかったら評価を真とします。
つまり、
,kencho('東京都',$x)
の評価では、ホーン節1つ1つとマッチングを行い、1つ目の引数が'東京都'である述語を検索することになります。unification.pのソースでは該当するホーン節がありますので、評価結果は真となります。
その時に、変数$xには、'新宿区'がマッチングされます。変数は、初期状態ではマッチングにおいて(なんでも良い)ということを示し、共に以降の評価においては、マッチングされた値を使用します。
,printn($x)
では、$xにマッチングされた、'新宿区'を出力することになります。
また、unification.pのコードにおいて、
,kencho('北海道',$x),printn($x)
としても、該当するホーン節が無い為、結果は何も表示されません。
ホーン節とその評価(3)バックトラック
ADP(Prolog)にはバックトラックと呼ばれる制御構造があります。
こちらも例を見てみます。このコートでは、全ての都県の県庁所在地が出力されます。
・コード(backtrack.p)
+kencho('茨城県','水戸市');
+kencho('栃木県','宇都宮市');
+kencho('群馬県','前橋市');
+kencho('埼玉県','さいたま市');
+kencho('千葉県','千葉市');
+kencho('東京都','新宿区');
+kencho('神奈川県','横浜市');
,kencho($x,$y),printn($x,":",$y),fail;
・実行結果
D:\sample>adp backtrack.p
茨城県:水戸市
栃木県:宇都宮市
群馬県:前橋市
埼玉県:さいたま市
千葉県:千葉市
東京都:新宿区
神奈川県:横浜市
ユニフィケーションの例との違いですが、都県の評価部分も変数になっています。
,kencho($x,$y)
上記の述語を評価しますと、全部のホーン節にマッチしますが、ADPでは先ずは先頭にあります、
+kencho('茨城県','水戸市');
にマッチして、先のprintn述語の評価を行います。その後、fail述語の評価を行いますが、fail述語は必ず評価に失敗します。
ADP(Prolog)では、述語の評価に失敗するとバックトラック(後戻り)を行います。
この例では、printn述語の再評価を行いますが、こちらも評価に失敗します。
次に、,kencho($x,$y)の再評価を行います。この再評価で、
+kencho('栃木県','宇都宮市');
にマッチし、再度printnの評価、failの評価、バックトラックと続き、結果としてkenchoの全てのホーン節とマッチします。最終的には全体がfailで終了します。
このようにADP(Prolog)ではバックトラックを使って全てのホーン節の評価を行うこともできます。
ホーン節とその評価(4)next述語(ADP独自の拡張)
バックトラックの例では、全てのホーン節kenchoの内容を出力するのにfail術語を使いましたが、fail述語では、評価に失敗するので全部のホーン節の内容を出力し終えた後は全体の評価も失敗します。
バックトラックを行いたいけど、全ての評価が終わった時は評価を続けたいということもあります。
next述語はそのような場合に使えます。以下再び例を見ています。
・コード(next.p)
+kencho('茨城県','水戸市');
+kencho('栃木県','宇都宮市');
+kencho('群馬県','前橋市');
+kencho('埼玉県','さいたま市');
+kencho('千葉県','千葉市');
+kencho('東京都','新宿区');
+kencho('神奈川県','横浜市');
,$c = 0 ,kencho($x,$y) ,printn($x,":",$y) ,$c = $c + 1 ,next ,printtn($c,"件");
・実行結果
D:\sample>adp next.p
茨城県:水戸市
栃木県:宇都宮市
群馬県:前橋市
埼玉県:さいたま市
千葉県:千葉市
東京都:新宿区
神奈川県:横浜市
7件
少し、プログラムが複雑になりましたが、$cでマッチした個数を数えながらnext述語でバックトラックを行い、全てのホーン節のマッチングが終了したら、next述語の次のprintn述語で、マッチした件数を出力しています。
このnext述語ですが、私が知る限り、ADPオリジナルの機能になります。next述語により非常にスッキリとループが書けます。
ホーン節とその評価(5) ! - カット述語
ルーターのパケットの許可、禁止ルールによくあるのですが、ルールを上から順に実行して、一致したらそれで評価終了ということがしたいことがあります。このような場合に、! カット述語を使います。
以下、年齢別の料金計算にカットを使ったコード例を示します。
・カットを使ったコード例(cut1.p)
+calc_age_price($age, $price, 0), $age < 2, !; # -- (1)
+calc_age_price($age, $price, $result), $age < 12, $result = $price / 2, !; # -- (2)
+calc_age_price($age, $price, $price); # -- (3)
,calc_age_price( 0, 100, $result), printn("乳児料金:", $result), next; # 乳児料金を表示
,calc_age_price( 10, 100, $result), printn("子供料金:", $result), next; # 子供料金を表示
,calc_age_price( 20, 100, $result), printn("大人料金:", $result), next; # 大人料金を表示
・実行結果
D:\sample>adp cut.p
乳児料金:0
子供料金:50
大人料金:100
年齢別の料金が計算されています。よく見ると気づくかと思いますが、乳児の年齢は(2)の条件(12未満)に合致します。従いましてnext述語でバックトラックすると(2)も実行されますが、カット述語のおかげで(2)の評価は行われません。カット述語はこのようにホーン節に対して一度マッチしたものは二度とマッチさせないという機能があります。以下、カットを外した例を掲載ます。
・カットを使わないコード例(cut2.p)
+calc_age_price($age, $price, 0), $age < 2; # -- (1)
+calc_age_price($age, $price, $result), $age < 12, $result = $price / 2; # -- (2)
+calc_age_price($age, $price, $price); # -- (3)
,calc_age_price( 0, 100, $result), printn("乳児料金:", $result), next; # 乳児料金を表示
,calc_age_price( 10, 100, $result), printn("子供料金:", $result), next; # 子供料金を表示
,calc_age_price( 20, 100, $result), printn("大人料金:", $result), next; # 大人料金を表示
・実行結果
D:\sample>adp cut2.p
乳児料金:0
乳児料金:50
乳児料金:100
子供料金:50
子供料金:100
大人料金:100
乳児料金が3回出てきています。カットを使わないで、乳児料金を正しく算出させる為には、子供料金と大人料金に正しく条件を入れます。(2)の子供料金の場合は、
$age >= 2, $age < 12
とし、(3)の大人料金の場合は、
$age >= 12
とします。
*ADPではこのように条件を手軽に記載できますが、バックトラックが発生した場合、ホーン節は出現順で評価されます。カットを使うと条件式を記載する手間が省けますが、評価順序を意識する必要があります。