List of lists into modified single list

2019-08-02 09:17发布

These are predicates which reads from input file

read_line(L,C) :-
    get_char(C),
    (isEOFEOL(C), L = [], !;
        read_line(LL,_),% atom_codes(C,[Cd]),
        [C|LL] = L).

%Tests if character is EOF or LF.
isEOFEOL(C) :-
    C == end_of_file;
    (char_code(C,Code), Code==10).

read_lines(Ls) :-
    read_line(L,C),
    ( C == end_of_file, Ls = [] ;
      read_lines(LLs), Ls = [L|LLs]
    ).

Input file:

A B
C D
E F
G H

read_lines(L) returns L = [[A, ,B],[C, ,D],[E, ,F],[G, ,H]]. My goal is to replace all the spaces and merge list of lists into single list. So expected output should look like: L = [A-B,C-D,E-F,G-H]. What I got so far is modified read_line function:

read_line(L,C) :-
    get_char(C),
    ( (char_code(C,Code), Code == 32)
        -> C = '-'
        ; C = C),
    (isEOFEOL(C), L = [], !;
        read_line(LL,_),% atom_codes(C,[Cd]),
        [C|LL] = L).

When I use it, Prolog says Syntax error: Unexpected end of file. What's wrong with that?

标签: prolog
1条回答
成全新的幸福
2楼-- · 2019-08-02 10:15

The problem is in this code:

( (char_code(C,Code), Code == 32)
    -> C = '-'
    ; C = C),

If a space character was read into variable C, char_code binds Code to 32, and the condition is true. Then Prolog tries to unify C with '-', but C is already bound to ' '! This fails, so your read_line call fails and leaves some unconsumed input on the standard input stream. The next time Prolog tries to read input from you, it actually reads that remaining input.

The underlying cause of the problem is that you seem to be trying to "reassign" the variable C. That is not possible in Prolog; once a variable is bound, it can only become unbound on backtracking.

Use a new variable, something like this:

( (char_code(C,Code), Code == 32)
    -> NewC = '-'
    ; NewC = C),

with corresponding uses of NewC where appropriate.

查看更多
登录 后发表回答