序言 - 不寻常的利弊语法列表(Prolog - unusual cons syntax for l

2019-06-23 09:39发布

我所遇到李纳什的论文的Prolog语法的陌生位在序言高阶逻辑编程 。 下面是从纸张的第一个代码示例:

% insertion sort (simple version)
isort([], []).
isort(A.As, Bs) :-
    isort(As, Bs1),
    isort(A, Bs1, Bs).

% insert number into sorted list
insert(N, [], [N]).
insert(N, H.L, N.H.L) :-
    N =< H.
insert(N, H.LO, H.L) :-
    N > H,
    insert(N, LO, L).

我的困惑是A.Asisort(A.As, Bs) :- 从上下文中,这似乎是一个替代利弊语法列表,相当于isort([A|As], Bs) :-

以及NHL似乎是更方便的方式来表达[N|[H|L]]

但SWI序言不会接受这种特殊的语法(除非我做错了什么)。

有谁认识它? 是我的假设是否正确? 这Prolog的解释器接受为有效的语法?

Answer 1:

点运算符用于列出了1972年的第一个Prolog的系统,写在大陵W,有时也被称为Prolog的0它是由LISP系统类似符号的启发。 以下是为例从纸张的Prolog的诞生由阿莱恩·科尔默劳尔和菲利普鲁塞尔-序言的非常创造者。

+ELEMENT(*X, *X.*Y).
+ELEMENT(*X, *Y.*Z) -ELEMENT(*X, *Z).

此时, []曾经是NIL

下一Prolog的版本,由Battani&马龙尼Fortran语言编写的,用来例区分原子和变量。 然后DECsystem 10的Prolog引入的方括号替换nilX.Xs[][X,..Xs]其中在DECsystem 10的更高版本接收[X|Xs]作为替代。 在ISO Prolog中,只有[X|Xs] .(X,Xs)和作为典型的语法'.'(X,Xs)

请注意,该点在ISO Prolog的许多不同的角色。 它提供已为

  • 随后当通过令牌结束 %或像空间,换行,TAB布局字符。

  • 在浮点数小数点 ,如3.14159

  • 图形令牌可形成焦炭的图形作为令牌=..

所以,如果你现在宣布. 作为中缀运算符,你必须非常小心。 无论什么你写什么Prolog的系统会读取。 一个单一的额外空间可以改变一个词的含义。 考虑两个数字列出了两种写法:

[1,2.3,4]. [5].
1 .2.3.4.[]. 5.[].

请注意,您必须后添加一个空格1 。 在此背景下,在数字前面的额外的空白可能会改变你的术语的含义。 像这样:

[1|2.3]. [4]. 5. [].
1 .2.3. 4.[]. 5. [].

下面是这可能是更加有说服力的一个例子:

[1,-2].
1.(-2).[].

负数需要点名单内圆括弧。

今天,只有YAP和XSB留下了仍然提供缀. 默认情况下-和他们做不同的看法 。 而XSB甚至不认识上面的点语法:你需要周围的一些非负数的圆括号。

你写NHL似乎是一个更方便的方式来表达[N|[H|L]] 有一个简单的原则进行的拇指在ISO Prolog的简化这样的表达式:当你的列表中看到令牌|[立即在彼此之后,则可以通过替换它们, (和删除对应的]在右侧)。 所以,你现在可以这样写: [N,H|L]看起来并不那么糟糕。

您可以使用规则还向另一个方向。 如果我们有一个列表[1,2,3,4,5]我们可以用| 为“刀片”,例如: [1,2,3|[4,5]]


另一句话,因为你正在阅读纳什的论文:在此期间,这是很好理解的 ,只有call/N是需要! 和ISO Prolog的支持call/1call/2call/8



Answer 2:

是的,你说得对,点它的利弊清单中缀操作符。 它实际上是由ISO Prolog的标准要求,但通常是隐藏的。 我发现(和使用),其前语法一段时间:

:- module(eog, []).
:- op(103, xfy, (.)).

% where $ARGS appears as argument, replace the call ($ARGS) with a VAR
% the calle goes before caller, binding the VAR (added as last ARG)
funcs(X, (V, Y)) :-
    nonvar(X),
    X =.. W.As,

    % identify meta arguments
    (   predicate_property(X, meta_predicate M)
        % explicitly exclude to handle test(dcg)
        % I'd like to handle this case in general way...
    ,   M \= phrase(2, ?, ?)
    ->  M =.. W.Ms
    ;   true
    ),

    seek_call(As, Ms, Bs, V),
    Y =.. W.Bs.

% look for first $ usage
seek_call([], [], _Bs, _V) :-
    !, fail.
seek_call(A.As, M.Ms, A.Bs, V) :-
    M @>= 0, M @=< 9, % skip meta arguments
    !, seek_call(As, Ms, Bs, V).
seek_call(A.As, _, B.As, V) :-
    nonvar(A),
    A = $(F),
    F =.. Fp.FAs,
    (   current_arithmetic_function(F) % inline arith
    ->  V = (PH is F)
    ;   append(FAs, [PH], FBs),
        V =.. Fp.FBs
    ),
    !, B = PH.
seek_call(A.As, _.Ms, B.As, V) :-
    nonvar(A),
    A =.. F.FAs,
    seek_call(FAs, Ms, FBs, V),
    !, B =.. F.FBs.
seek_call(A.As, _.Ms, A.Bs, V) :-
    !, seek_call(As, Ms, Bs, V).

:- multifile user:goal_expansion/2.
user:goal_expansion(X, Y) :-
    ( X = (_ , _) ; X = (_ ; _) ; X = (_ -> _) )
    -> !, fail % leave control flow unchanged (useless after the meta... handling?)
    ;  funcs(X, Y).

/* end eog.pl */

我被告知反对。 实际上,在[A | B]语法它的演变。 运营商,推出了可读性。

OT:那是什么码?

它上面的代码是我尝试用功能甜甜的Prolog。 即,介绍了请求,借助于$ ,通过算术表达式需要(例如)的临时变量

fact(N, F) :-
     N > 1 -> F is N * $fact($(N - 1)) ; F is 1.

每个$引进的变量。 扩建后,我们有一个更传统的事实/ 2

?- listing(fact).
plunit_eog:fact(A, C) :-
    (   A>1
    ->  B is A+ -1,
        fact(B, D),
        C is A*D
    ;   C is 1
    ).

我们有很多的表达,这可能是有用的...



Answer 3:

这句法来自NU-Prolog的。 见这里 。 这可能只是正常的名单仿/ 2重新定义为中缀操作,而不需要一个尾随空列表“”:

?- L= .(a,.(b,[])).
L = [a,b]
Yes (0.00s cpu)
?- op(500, xfy, '.').
Yes (0.00s cpu)
?- L = a.b.[].
L = [a,b]
Yes (0.00s cpu)


文章来源: Prolog - unusual cons syntax for lists