问题
We have a relatively simple assignment that I understand in theory but I think I just don't quite understand Prolog's syntax enough to get that into code. Basically, we have a list of English notations that represent operations in C. They're stored as a list when they're passed to our Prolog program. For example:
add 4 to 3
is
[add, 4, to, 3]
We need to write a function that takes that list an returns the equivalent. So if I called
english2C([add,4,to,3], C).
C = 4+3
It would bind C to the result. So the data structure itself would be something like +(4(3)). We have a list of such English notation we have to translate, so it's a finite number. It's not like we have to account for all possibilities. There are also combinations, where they take two operations and combine them (with a comma in between)
english2C([add,3,to,5,',',then,subtract,7], C).
C = 3+5-7
I'm just somewhat confused as to how to start. I know I can take the very first element of the list and that will always be an operator (+,-,*, etc etc) and then I can just recursively go through the list looking for the operands. The problem there is for things that require order of operations, like "add 3 to 5 then multiply by 4", which should be represented as (3+5)*4 but if you just translate it directly you get 3+5*4.
Oh and we have to see if we can get it to run backwards (give it a C statement (3+5) and translate back to english (add 3 to 5)). That part I don't really have an idea for at all.
EDIT: There's a large enough permutations of possible English notations that I can't just pattern match everything. I get the idea that what I need to do is match the first operator with it's corresponding arithmetic symbol then find the operands. For a combinational statement, that would be the first part (so I would have 3+5) and then there would be a comma followed by the next statement. By the way, the combinational statements can be as long as they want, so it's not just two statements and I'm done.
回答1:
If there is a reasonable small number of patterns, you could do:
english2C([add,X,to,Y], R) :- R is X+Y.
english2C([add,A,to,B,',',then,subtract,C], R) :- R is A+B-C.
edit
Those rules above compute the value. To translate, we can use DCG for matching, it's working 'backwards' as well.
english2C(In, R) :- phrase(toe(R), In, []).
toe(X+Y) --> [add,X,to,Y].
toe(X*Y) --> [multiply,X,by,Y].
toe(L-R) --> toe(L), [',',then,subtract,R].
test:
?- english2C(X,3+6).
X = [add, 3, to, 6].
edit sorry, I forgot a cut. With that added, I get
?- english2C([add,3,to,5,',',then,subtract,4],X).
X = 3+5-4.
?- english2C(L,3+5-4).
L = [add, 3, to, 5, ',', then, subtract, 4].
without, there is the loop after ;
?- english2C([add,3,to,5,',',then,subtract,4],X).
X = 3+5-4 ;
^CAction (h for help) ? goals
[698,875] toe(_G2096630, [add, 3, to, 5, ',', then, subtract, 4], _G2096652)
[698,874] toe('<garbage_collected>', '<garbage_collected>', _G2096652)
...
It's a single point change: do you prefer to find it yourself?
来源:https://stackoverflow.com/questions/13257058/prolog-translating-english-to-c