4
votes

Here is a simple Prolog program to exhibit a problem that I currently have with my real code.

I am trying to write a Brainf*ck interpreter in Prolog, but it is not returning the right Output

I am running bf("+.", Output)

Expected Return - Output = [1]

Actual Return - Output = [].

Output looses its value when it returns to iterateProg(Prog,Output) in bf2.

Program is as follows:

bf2(Prog,Output):-
    iterateProg(Prog,Output).

iterateProg([],_):- !.
iterateProg(Prog, Output):-
    checkInstruction(Prog,Output, NewProg, NewOutput),
    iterateProg(NewProg, NewOutput).

checkInstruction([Plus|ProgTail],Output,ProgTail,Output):-
    char_code('+',Plus)
    %increase memory by 1 for printing later.
    .

checkInstruction([Period|ProgTail], Output, ProgTail, NewOutput):-
    char_code('.',Period),
    %take the value in memory from addition just now, we will assume it is 1
    append(Output,[1],NewOutput).
1
Please check my answer. I made a mistake in the comment.nhahtdh

1 Answers

1
votes

Your predicate bf2(Prog, Output) has the meaning of: this program Prog correspond with this output Output - so the Output in the bf2 predicate and also in iterateProg should contains the full output.

So in checkInstruction predicate, the first 2 arguments should contain the full program and the full output, and the last 2 arguments should contain the partial program and the corresponding partial output.

Therefore, you should append the [1] with NewOutput, to produce the final output in Output for the second rule of checkInstruction predicate. You should rename the New... with a different name - since it is actually the partial/"tail" program and corresponding output.

append([1], NewOutput, Output)

Note the order (I was inaccurate in the comment). [1] is the output for the current instruction, and it should precede the output of the instruction in ProgTail.

By the way, bf2 predicate is unnecessary - since it call iterateProg predicate with exact same arguments.

Another thing is iterateProg([],_) should be iterateProg([],[]) since an empty program should correspond with empty output. (The converse is not true, so you should never put a cut ! here, if you have learned about it).