2017-12-18 5 views
0

Unten sind die Codes, die ich kam. Hier gibt es jedoch zwei Probleme. Zuerst wird nur der erste Wert von X angezeigt, der 1. Ist. Wenn Y falsch ist, springt er nicht zurück zu menu1. Ich hoffe, dass ich dir dabei helfen kann.Benötigen Sie eine vollständige Liste der Ausgabe

time(office_hour,1). 
time(office_hour,2). 
menu1 :- 
    write('Input time'),nl, 
    read(Y),nl,time(Y,X),nl,write(X),nl,menu1. 

Dies ist das Beispiel des Szenarios. Wie unten zu sehen ist, wird nur der Wert 1 angezeigt. Wie kann man auch den Wert 2 anzeigen? Sry, ich bin nur ein Neuling

?-menu1. 
Input time 
office_hour. 
1. 
Input time 
+0

Sie sollten auch ein Beispiel für das Verhalten posten. Vor allem, was gibst du ein? Wenn es nicht "office_hour" ist, wird "time/2" fehlschlagen, bevor es "menu1/0" aufruft. –

+0

sry, ich habe meinen Beitrag bereits aktualisiert. Auch was ist das 'time/2' und' menu1/0'? Ich erinnere mich nicht an einen solchen Begriff von meinem Dozenten. – Kimchi

+0

@Kimchi es ist in Prolog Dokumentation, wenn Sie es betrachten. Das '/ n' bedeutet' n' Argumente. Also ist "time/2" 'time' mit 2 Argumenten. Wenn es eine "Zeit" mit 3 Argumenten gäbe, wäre dies ein anderes Prädikat und wird als "time/3" beschrieben. – lurker

Antwort

0

Sie müssen Prolog zu denselben Weg zurückverfolgen, damit alle Lösungen zu bekommen. Das Problem mit Ihrem Prädikat ist, dass es einen rekursiven Aufruf durchführt, bevor es zurückverfolgen kann. Außerdem werden Sie für die nächste Menüaufforderung eine Ebene tiefer recursen, was wahrscheinlich nicht gut ist, da es ständig mehr Stapel verbraucht, da es auf Benutzereingaben reagiert.

Hier ist ein anderer Ansatz, mit dem repeat/0 Prädikat zusammen mit fail/0. repeat/0 ist einfach erfolgreich, was es ermöglicht, während des Backtracking nach Lösungen zu suchen. Und fail/0 schlägt immer fehl, was Backtracking erzwingt. Es ist eine gebräuchliche Art, eine kontinuierliche Wiederholungsschleife zu erstellen, und eignet sich gut zum Wiederholen eines Menüs. Ich habe auch die nl/0 Verwendung ein wenig angepasst, um die Ausgabe ein wenig sauberer zu machen, und ich habe time/2 umbenannt, da es einfach zu generisch ist und möglicherweise mit einem Systemprädikat kollidieren könnte.

item_time(office_hour,1). 
item_time(office_hour,2). 

menu1 :- 
    repeat, 
    nl, write('Input time'), nl, 
    read(Y), 
    item_time(Y, X), 
    write(X), nl, 
    fail. 

Dies ergeben:

| ?- menu1. 

Input time 
office_hour. 
1 
2 

Input time 
foo. 

Input time 
... 

Was hier passiert, ist, dass fail/0 wird das Prädikat Klausel verursachen die write(X), nl und zum time(Y, X) zurückzuverfolgen, durch die mit den alternativen Lösungen treffen werden, auf denen gelingen Lösungen, und dann wieder auf die write(X), nl gehen. Wenn time(Y, X) keine Lösungen mehr findet, schlägt es schließlich fehl und die Klausel rückt den gesamten Weg zurück zum repeat/0 Aufruf, der immer erfolgreich ist. Dies führt dazu, dass die Ausführung wieder auf nl, write('Input time'), ... vorrückt.

Wie Sie sehen können, wird die Eingabe von etwas unerkannt nur noch einmal aufgefordert. Um dies zu vervollständigen, könnten Sie Atome hinzufügen, die als "ruhig" erkannt werden, und Sie könnten eine Diagnosemeldung schreiben, wenn Sie eine Eingabe erhalten, die in Ihrer Datenbank nicht existiert. Das wäre eine gute Übung zum Lernen.

+0

Kann ich wissen, was 'fail/0' macht? Ich googelte und es sagt 'immer scheitern' ... – Kimchi

+0

Sie haben festgestellt, dass Prädikate ausfallen können? Wie wenn man 'time/2' mit etwas anderem als' office_hour' als ersten Parameter aufruft.Es ist so, aber unabhängig von Variablen. Es scheitert immer. Es ist nützlich, wenn Sie einige Nebenwirkungen wie Drucken vor dem Fehler machen möchten. –

+0

@Kimchi Ich erweiterte meine Antwort zu erklären, scheitern ein wenig. Ein gemeinsames Prolog-Muster ist die "Wiederholungs-Fehler-Schleife". – lurker

0

Das zweite Problem:

menu1 :- 
    write('Input time'),nl, 
    read(Y),nl, 
    (time(Y,X) -> 
    write(X),nl 
    ; write('bad input'),nl), 
    menu1. 
+0

Was macht '(Zeit (Y, Z) -> ...)' tatsächlich? ich meine die Klammern – Kimchi

+0

Wenn-dann-sonst, versuchen Sie, das Handbuch zu lesen :) –

+0

was ist, wenn ich nur schreiben Zeit (Y, X) -> schreiben (X), nl ; schreiben ('schlechte Eingabe'), nl 'ohne Klammern? ich weiß, '->' bedeutet wenn-dann-sonst – Kimchi

Verwandte Themen