Prolog - unusual cons syntax for lists

后端 未结 3 1369
囚心锁ツ
囚心锁ツ 2020-12-11 14:29

I have come across an unfamiliar bit of Prolog syntax in Lee Naish\'s paper Higher-order logic programming in Prolog. Here is the first code sample from the paper:<

3条回答
  •  独厮守ぢ
    2020-12-11 15:22

    Yes, you are right, the dot it's the list cons infix operator. It's actually required by ISO Prolog standard, but usually hidden. I found (and used) that syntax some time ago:

    :- 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 */
    

    I was advised against it. Effectively, the [A|B] syntax it's an evolution of the . operator, introduced for readability.

    OT: what's that code?

    the code above it's my attempt to sweeten Prolog with functions. Namely, introduces on request, by means of $, the temporary variables required (for instance) by arithmetic expressions

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

    each $ introduce a variable. After expansion, we have a more traditional fact/2

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

    Where we have many expressions, that could be useful...

提交回复
热议问题