2017-09-26 2 views
0

ich die folgenden Operatoren definiert haben:Prolog - übersetzen Betreiber

:- op(200, xfx, plus). 
:- op(100, xfx, times). 

ich ein Prädikat übersetzen/2 so implementieren möchten, dass ein gegebener Begriff, der nur aus Zahlen und die Operatoren plus und Zeiten, so dass diese Betreiber wird in ihre entsprechenden arithmetischen Operatoren übersetzt: + und *.

Zum Beispiel:

?- translate((4 plus 5), Result). 
    Result = 4 + 5. 

?- translate(((3 times 2) times 7 plus 4), Result). 
    Result = (3 * 2) * 7 + 4. 

?-translate((5 times 3 plus 4 times 5)), Result). 
    Result = 5 * 3 + 4 * 5. 

Update: Allright so dass der Code Ive kommen bisher mit ist:

replace([], _, _, []). 

replace([El1|List], El1, El2, [El2|Result]) :- 
replace(List, El1, El2, Result), !. 

replace([H|List], El1, El2, [H|Result]) :- 
replace(List, El1, El2, Result). %replaces an element in a list with 
            %another element. 


translate(Term, ListResult2):- 
    Term =.. ListResult, 
    replace(ListResult, times, *, ListResult1), 
    replace(ListResult1, plus, +, ListResult2). %This will make a list of a 
               % a term and replace the 
               %operators the right way.         

Sorry für nicht hinzugefügt spezifischere Kommentare darauf, wie meine Klauseln arbeiten. Die Idee ist hier, eine Liste zu erstellen, in der die Operatoren durch die entsprechenden Terme ersetzt werden. Mein Problem ist, dass die Ausgabe eine Liste anstelle eines Begriffs ist. Gibt es eine Möglichkeit umzukehren, was ich mit dem = .. Operator gemacht habe ???

+0

Was haben Sie versucht, sich selbst? Was funktioniert nicht? Auf welche Probleme stoßen Sie? –

Antwort

0

Ich denke, ich fand die Lösung, es war etwas syntaktisches, das ich verpasste. Ich habe vergessen, dass der Operator = .. Lösungen für beide Seiten auf der Laufzeit bieten kann. also X = .. [1,2,3] wandelt die Liste [1,2,3] in den entsprechenden Ausdruck um und umgekehrt. Die Lösung sieht wie folgt aus:

replace([], _, _, []). 

replace([El1|List], El1, El2, [El2|Result]) :- 
replace(List, El1, El2, Result), !. 

replace([H|List], El1, El2, [H|Result]) :- 
replace(List, El1, El2, Result). 


translate(Term, TrueResult):- 
    Term =.. ListResult, 
    replace(ListResult, times, *, ListResult1), 
    replace(ListResult1, plus, +, ListResult2), 
    TrueResult =.. ListResult2. 
+0

Was ist, wenn Ihre Beispiele rekursiv sind? Wie '(a plus b) mal c'? –

+0

Gefeiert zu früh ... Also ich muss überprüfen, ich plus/mal ist ein Teil des Mitglieds der Liste und dann ersetzen statt nur plus/Zeiten als ein mögliches Mitglied zu sehen. –

0

So etwas kann Ihre Bedürfnisse anzupassen:

:- op(200, yfx, plus). 
:- op(100, yfx, times). 

translate(Z, Z1):- 
    (
    nonvar(Z), 
    Z \= _ plus _, 
    Z \= _ times _ 
) -> Z1=Z ; 
    (
    member(Z-Z1, [(X plus Y)-(X1 + Y1), (X times Y)-(X1 * Y1)]), 
    translate(X, X1), 
    translate(Y, Y1) 
). 

Testfälle:

?- translate((4 plus 5), Result). 
Result = 4+5 
?- translate(((3 times 2) times 7 plus 4), Result). 
Result = 3*2*7+4 
?- translate((5 times 3 plus 4 times 5), Result). 
Result = 5*3+4*5 
?- translate((a plus b) times c, Result). 
Result = (a+b)*c 
?- translate(5 times (3 plus 4) times 5, Result). 
Result = 5* (3+4)*5 
+0

Vielen Dank !! Denkst du, dass es auch mit dem = .. Ansatz gemacht werden kann, den ich oben gezeigt habe, oder wird es am Ende zu unpraktisch sein? –

+0

@ WillemvanderSpek: Ich denke, Sie könnten es mit '= ..' arbeiten, obwohl Sie Ihre Prozedur ändern sollten, um sich rekursiv mit jedem Operanden selbst aufzurufen. – gusbro