Domanda

C'è un modo per fare un caso nel prologo, per esempio se una variabile è 0, quindi fare alcune azioni (testo scrittura al terminale). Un altro non è nemmeno necessario, ma non riesco a trovare alcuna documentazione di se.

È stato utile?

Soluzione

Un predicato prologo di serie farà questo.

   isfive(5). 

valuterà a true se lo si chiama con 5 e di rifiuto (return false) se lo si esegue con qualsiasi altra cosa. Per non uguale si utilizza \ =

isNotEqual(A,B):- A\=B.

Tecnicamente è non unifica, ma è simile a non uguale.

Scopri Prolog Ora è un buon sito web per l'apprendimento Prolog.

Modifica: Per aggiungere un altro esempio.

isEqual(A,A). 

Altri suggerimenti

Sì, c'è un tale costrutto di controllo ISO Prolog, chiamato ->. Si utilizza in questo modo:

( condition -> then_clause ; else_clause )

Ecco un esempio che utilizza una catena di else-if-clausole:

(   X < 0 ->
    writeln('X is negative.  That's weird!  Failing now.'),
    fail
;   X =:= 0 ->
    writeln('X is zero.')
;   writeln('X is positive.')
)

Si noti che se si omette l'altra clausola, la condizione in mancanza significa che l'intero caso-statement fallirà. Pertanto, vi consiglio sempre compreso il else-clausola (anche se è solo true).

Prolog predicati 'Unificare' -

Quindi, in un langauge imperativo che avrei scritto

function bazoo(integer foo)
{
   if(foo == 5)
       doSomething();
   else
       doSomeOtherThing();
}

In Prolog mi piacerebbe scrivere

bazoo(5) :-  doSomething.
bazoo(Foo) :- Foo =/= 5, doSomeOtherThing.

, che, quando si capisce entrambi gli stili, è in realtà molto più chiara.
"Sono bazoo per il caso speciale quando foo è 5"
"Sono bazoo per il caso normale quando foo non è 5"

Ho trovato questo utile per l'utilizzo di un se dichiarazione in una regola.

max(X,Y,Z) :-
    (  X =< Y
    -> Z = Y
    ;  Z = X
    ).

Grazie alla http: //cs.union. edu / ~ striegnk / imparare-Prolog-ora / html / node89.html

Per prima cosa, ricordano un po 'di logica classica del primo ordine:

  

" Se P poi Q altro R" è equivalente a "(P e Q) o (non_P e R)".


Come possiamo esprimere "if-then-else" come che in Prolog?

Facciamo il seguente esempio concreto:

  

Se X è un membro della lista [1,2] poi X uguale 2 altro X uguale 4.

può abbinare al di sopra del modello ( " Se P poi Q altro R"), se ...

  • condizione P è list_member([1,2],X),
  • negato condizione non_P è non_member([1,2],X),
  • conseguenza Q è X=2, e
  • R alternativa è X=4.

Per esprimere lista (non) l'appartenenza in modo puro, definiamo:

list_memberd([E|Es],X) :-
   (  E = X
   ;  dif(E,X),
      list_memberd(Es,X)
   ).

non_member(Es,X) :-
   maplist(dif(X),Es).

assegno emise modi diversi di esprimere "if-then-else" in Prolog!

  1. (P,Q ; non_P,R)

    ?-      (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4).
    X = 2 ; X = 4.
    ?- X=2, (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=2.
    X = 2 ; false.
    ?-      (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=2.
    X = 2 ; false.
    ?- X=4, (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=4.
    X = 4.
    ?-      (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=4.
    X = 4.
    

    Correttezza punteggio 5/5. Efficienza punteggio 3/5.

  2. (P -> Q ; R)

    ?-      (list_memberd([1,2],X) -> X=2 ; X=4).
    false.                                                % WRONG
    ?- X=2, (list_memberd([1,2],X) -> X=2 ; X=4), X=2.
    X = 2.
    ?-      (list_memberd([1,2],X) -> X=2 ; X=4), X=2.
    false.                                                % WRONG
    ?- X=4, (list_memberd([1,2],X) -> X=2 ; X=4), X=4.
    X = 4.
    ?-      (list_memberd([1,2],X) -> X=2 ; X=4), X=4.
    false.                                                % WRONG
    

    Correttezza punteggio 2/5. Efficienza punteggio 2/5.

  3. (P *-> Q ; R)

    ?-      (list_memberd([1,2],X) *-> X=2 ; X=4).
    X = 2 ; false.                                        % WRONG
    ?- X=2, (list_memberd([1,2],X) *-> X=2 ; X=4), X=2.
    X = 2 ; false.
    ?-      (list_memberd([1,2],X) *-> X=2 ; X=4), X=2.
    X = 2 ; false.
    ?- X=4, (list_memberd([1,2],X) *-> X=2 ; X=4), X=4.
    X = 4.
    ?-      (list_memberd([1,2],X) *-> X=2 ; X=4), X=4.
    false.                                                % WRONG
    

    Correttezza punteggio 3/5. Efficienza punteggio 1/5.


(preliminare) sintesi:

  1. (P,Q ; non_P,R) è corretto, ma necessita di un'implementazione discreta di non_P.

  2. (P -> Q ; R) perde semantica dichiarativa quando istanziazione è insufficiente.

  3. (P *-> Q ; R) è "meno" incompleta di (P -> Q ; R), ma ha ancora guai simili.


Fortunatamente per noi, ci sono alternative: Inserisci il if_/3 logicamente monotono controllo costrutto!

Possiamo usare if_/3 unitamente alla lista-membership reificata predicato di memberd_t/3 in questo modo:

?-      if_(memberd_t(X,[1,2]), X=2, X=4).
X = 2 ; X = 4.
?- X=2, if_(memberd_t(X,[1,2]), X=2, X=4), X=2.
X = 2.
?-      if_(memberd_t(X,[1,2]), X=2, X=4), X=2.
X = 2 ; false.
?- X=4, if_(memberd_t(X,[1,2]), X=2, X=4), X=4.
X = 4.
?-      if_(memberd_t(X,[1,2]), X=2, X=4), X=4.
X = 4.

Correttezza punteggio 5/5. Efficienza punteggio 4/5.

La cosa migliore da fare è quella di utilizzare il cosiddetto cuts, che ha il ! simbolo.

if_then_else(Condition, Action1, Action2) :- Condition, !, Action1.  
if_then_else(Condition, Action1, Action2) :- Action2.

Quanto sopra è la struttura di base di una funzione condizione.

Per esemplificare, ecco la funzione max:

max(X,Y,X):-X>Y,!.  
max(X,Y,Y):-Y=<X.

Suggerisco di leggere ulteriore documentazione sui tagli, ma in generale sono come punti di interruzione. Es .: Nel caso la prima funzione max restituisce un valore vero, la seconda funzione non è verificato.

PS: Sono abbastanza nuovo per Prolog, ma questo è quello che ho scoperto

.

Ci sono essenzialmente tre diversi modi per esprimere qualcosa come if-then-else in Prolog. Per confrontare le considerano char_class/2. Per a e b la classe dovrebbe essere ab e other per tutti gli altri termini. Si potrebbe scrivere questo maldestramente in questo modo:

char_class(a, ab).
char_class(b, ab).
char_class(X, other) :-
   dif(X, a),
   dif(X, b).

?- char_class(Ch, Class).
   Ch = a, Class = ab
;  Ch = b, Class = ab
;  Class = other,
   dif(Ch, a), dif(Ch, b).

Per le cose di scrittura in modo più compatto, un if-then-else è necessaria costrutto. Prolog è un built-in uno:

?- ( ( Ch = a ; Ch = b ) -> Class = ab ; Class = other ).
   Ch = a, Class = ab.

Anche se questa risposta è il suono, è incompleta. Proprio la prima risposta da ( Ch = a ; Ch = b ) è dato. Le altre risposte sono tagliate via. Non molto relazionale, anzi.

Un costrutto meglio, spesso chiamato un "taglio soft" (non credo che il nome, un taglio è un taglio è un taglio), cede leggermente migliori risultati (questo è in YAP):

?- ( ( Ch = a ; Ch = b ) *-> Class = ab ; Class = other ).
   Ch = a, Class = ab
;  Ch = b, Class = ab.

In alternativa, SICStus ha if/3 con semantica molto simili:

?- if( ( Ch = a ; Ch = b ), Class = ab , Class = other ).
   Ch = a, Class = ab
;  Ch = b, Class = ab.

Quindi l'ultima risposta è ancora soppressa. Ora inserite library(reif) per SICStus , YAP , e SWI . Installarlo e dire:

?- use_module(library(reif)).

?- if_( ( Ch = a ; Ch = b ), Class = ab , Class = other ).
   Ch = a, Class = ab
;  Ch = b, Class = ab
;  Class = other,
   dif(Ch, a), dif(Ch, b).

Si noti che tutte le if_/3 viene compilato via ad un selvaggiamente nidificato if-then-else per

char_class(Ch, Class) :-
   if_( ( Ch = a ; Ch = b ), Class = ab , Class = other ).

che si espande in YAP 6.3.4 a:

char_class(A,B) :-
   ( A\=a
   ->
     ( A\=b
     ->
       B=other
     ;
       ( A==b
       ->
         B=ab
       )
     ;
       A=b,
       B=ab
     ;
       dif(A,b),
       B=other
     )
   ;
     ( A==a
     ->
       B=ab
     )
   ;
     A=a,
     B=ab
   ;
     dif(A,a),
     ( A\=b
     ->
       B=other
     ;
       ( A==b
       ->
         B=ab
       )
     ;
       A=b,
       B=ab
     ;
       dif(A,b),
       B=other
     )
   ).

Programma Prolog in realtà è grande condizione per "se" con "poi" che stampa "è raggiunto Goal" e "altro", che stampa "Nessun sloutions è stato trovato". A, Bmeans "A è vero e B è vero", la maggior parte dei sistemi di prologo non cercherà di soddisfare "B" se "A" non è raggiungibile (cioè X=3, write('X is 3'),nl stamperà 'X è 3' quando X = 3, e lo farà nulla se X = 2).

(  A == B ->
     writeln("ok")
;
     writeln("nok")
),

È necessario il resto parte

Si consiglia di leggere Imparare Prolog Now! Capitolo 10.2 Utilizzando Cut . Ciò fornisce un esempio:

max(X,Y,Z) :- X =< Y,!, Y = Z.

Va detto,

Z è pari a Y se ! è vero (che sempre è) e è X <= Y.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top