Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Switch statements in Prolog

In Prolog predicates, I often write repetitive conditional statements like this one, but I wish they could be written more concisely:

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

Would it be possible to replace this series of conditional statements with a more concise switch-statement?

like image 620
Anderson Green Avatar asked Mar 03 '16 06:03

Anderson Green


People also ask

What type of statement is switch?

In computer programming languages, a switch statement is a type of selection control mechanism used to allow the value of a variable or expression to change the control flow of program execution via search and map.

How do switch statments work?

The body of a switch statement is known as a switch block. A statement in the switch block can be labeled with one or more case or default labels. The switch statement evaluates its expression, then executes all statements that follow the matching case label.

Does Prolog have if statements?

“prolog if” is a statement to support conditions of the application's data and its operations. It is a conditional function to display the required condition of the prolog programming language. It is a function to prove the true and false condition and operation of the given data or values using a programming language.


3 Answers

In Prolog it is quite easy to define your own control structures, using meta-predicates (predicates that take goals or predicates as arguments).

For example, you could implement a switch construct like

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

by defining

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

If necessary, this can then be made more efficient by compile-time transformation as supported by many Prolog systems (inline/2 in ECLiPSe, or goal expansion in several other systems).

And via operator declarations you can tweak the syntax to pretty much anything you like.

like image 153
jschimpf Avatar answered Nov 06 '22 06:11

jschimpf


It seems that multiple clauses are made for this use case and also quite concise.

output(javascript, Type, ["javascript", Type]).
output(ruby, Type, ["def", Type]).
output(java, Type, [Type]).
like image 34
coredump Avatar answered Nov 06 '22 06:11

coredump


slightly shorter:

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

idiomatic:

output(Lang, Type, Output) :-
  memberchk(Lang-Output, [
    javascript - ["function", Type],
    ruby - ["def", Type],
    java - [Type]
  ]).
like image 39
CapelliC Avatar answered Nov 06 '22 06:11

CapelliC