if else if else clause in prolog similar to C/C++

前端 未结 5 814
说谎
说谎 2021-01-18 14:53

In c language i have something like :

if(cond1)
{}
else if(cond2)
{}
else
{}

how is this possible in Prolog?

5条回答
  •  渐次进展
    2021-01-18 15:05

    The ->/2 is only needed if you want to impose a certain determinism. It acts like a local cut. But in case you want that your code keeps some non-determinism, it is not necessary to use ->/2.

    Take the following imperative code:

    boolean listOfBool(Object obj) {
       if (obj instanceof ConsCell) {
           if (((ConsCell)ob).head() instanceof Boolean) {
               return listOfBool(((ConsCell)ob).tail());
           } else {
               return false;
           }
      } else if (obj == null) {
           return true;
      } else {
           return false;
      }
    

    }

    This can be coded in Prolog without ->/2 as follows:

    % bool(+Bool)
    % bool(-Bool)
    bool(0).
    bool(1).
    
    % list_of_bool(+List)
    % list_of_bool(-List)
    list_of_bool(L) :-
        (L = [X|Y], bool(X), list_of_bool(Y);
         L = []).
    

    The advantage is now that it can be used to check lists of booleans and to generate lists of booleans:

    ?- list_of_bool([0,1,0]).
    Yes 
    ?- list_of_bool([0,1,2]).
    No
    ?- List=[_,_,_], list_of_bool(List).
    List = [0, 0, 0] ;
    List = [0, 0, 1] ;
    List = [0, 1, 0] ;
    List = [0, 1, 1] Etc..
    

    Generally the disjunction (;)/2 can be distributed over multiple clauses. If this is combined with moving unification (=)/2 into the head, then some speed can be gained, since the predicate is then usually better amenable to indexing.

    Here is how an alternative formulation of list_of_bool would look like by eliminating (;)/2 and (=)/2:

    % list_of_bool2(+List)
    % list_of_bool2(-List)
    list_of_bool2([X|Y]) :- bool(X), list_of_bool2(Y).
    list_of_bool2([]).
    

    The above works exactly the same (it actually works better, since in the first query no choice point is left, what the (;)/2 usually will not detect without (->)/2):

    ?- list_of_bool2([0,1,0]).
    Yes
    ?- list_of_bool2([0,1,2]).
    No
    ?- List=[_,_,_], list_of_bool(List).
    List = [0, 0, 0] ;
    List = [0, 0, 1] ;
    List = [0, 1, 0] ;
    List = [0, 1, 1] Etc..
    

    This is also how Prolog can be started. With rules only and no disjunction (;)/2 and no unification (=)/2. The later two are already there in the underlying Horn clauses.

    Suppose you have a Prolog without (;)/2 and no (=)/2, and you don't need a cut transparent (;)/2, then you could define these constructs by yourself as follows:

    X = X.
    
    (A ; _) :- A.
    (_ ; B) :- B.
    

    Bye

    Horn Clause
    http://en.wikipedia.org/wiki/Horn_clause

提交回复
热议问题