Инструкции Switch в Prolog

в предикатах пролога я часто пишу повторяющиеся условные утверждения, подобные этому, но я хотел бы, чтобы они были написаны более кратко:

output(Lang, Type, Output) :-   
    (Lang = javascript ->
        Output = ["function", Type];
    Lang = ruby ->
        Output = ["def", Type];
    Lang = java ->
        Output = [Type]).

можно ли заменить эту серию условных операторов более кратким оператором switch-statement?

3 ответов


в Prolog довольно легко определить свои собственные структуры управления, используя мета-предикаты (предикаты, которые принимают цели или предикаты в качестве аргументов).

например, вы можете реализовать конструкцию коммутатора, такую как

switch(X, [
    a : writeln(case1),
    b : writeln(case2),
    c : writeln(case3)
])

определение

switch(X, [Val:Goal|Cases]) :-
    ( X=Val ->
        call(Goal)
    ;
        switch(X, Cases)
    ).

при необходимости это можно сделать более эффективным путем преобразования времени компиляции, поддерживаемого многими системами Prolog (inline / 2 в ECLiPSe или расширение цели в нескольких других системный.)

и через объявления операторов вы можете настроить синтаксис почти на все, что вам нравится.


Кажется, что для этого случая использования сделано несколько предложений, а также довольно лаконично.

output(javascript, Type, ["javascript", Type]).
output(ruby, Type, ["def", Type]).
output(java, Type, [Type]).

немного короче:

output(Lang, Type, Output) :-   
    (Lang, Output) = (javascript, ["function", Type]) ;
    (Lang, Output) = (ruby, ["def", Type]) ;
    (Lang, Output) = (java, [Type]).

идиоматическое:

output(Lang, Type, Output) :-
  memberchk(Lang-Output, [
    javascript - ["function", Type],
    ruby - ["def", Type],
    java - [Type]
  ]).