调试序言中的一段代码

时间:2019-03-19 22:36:00

标签: prolog

Prolog中有一段代码,用于将txt文件转换为4个列表(每行3个1D_list,最后一个是2D_list,其余各行一个子列表。

inp :-
    open('3by3data.txt', read, Str),
    read_line_to_string(Str,Line),               %read  a line from Str(Stream)
        split_string(Line," ","",L_list1),       %Split a line into a list by " "
        maplist(atom_number,L_list1,RL), !,      %Conver atom list into number list
    read_line_to_string(Str,Line1),               %read a line from Str(Stream)
        split_string(Line1," ","",L_list2),       %Split a line into a list by " "
        maplist(atom_number,L_list2,FQty), !,    %Conver atom list into number list  

    read_line_to_string(Str,Line2),               %read a line from Str(Stream)
        split_string(Line2," ","",L_list3),       %Split a line into a list by " "
        maplist(atom_number,L_list3,WQty),!,     %Conver atom list into number list      
    read_Costs(Str,Costs),    
    write(RL),nl,write(FQty),nl,write(),nl,write(Costs),nl.


read_Costs(Str,Costs) :- 
        \+at_end_of_stream(Str),
        read_line_to_string(Str,Line3),        
        split_string(Line3," ","",L_list4),  %Split a line into a list by " "
        maplist(atom_number,L_list4,Costs1),%Conver atom list into number list 
        append([costs1],[Costs2],Costs),
        read_Costs(Str,Costs2).
read_Costs([],[]).

file.txt:

  3   4
  10 60 30 40
  50 30 60
  2 4  5  6
  7 8  9  4
  1 2  4  6
  ...
  =>
  [3,4]
  [10,60,30,40]
  [50,30,60]
  [[2,3,5,6],[7,8,9,4],[1,2,4,6],...]

以上代码中存在边界条件错误。

1 个答案:

答案 0 :(得分:1)

当然这行

  

append([costs1],[Costs2],Costs),

不起作用,因为错误地拼写了变量 Costs1,并且循环终止的替代子句-EOF-无法将流Str[]匹配。 / p>

关于代码的样式说明。像任何其他语言一样,在Prolog中,将可重复使用的“子例程”中的重复的通用功能分组是很有价值的。

read_line_to_string,split_string,maplist(atom_number)的组合经常使用。用它们作为服务谓词。

如果使用SWI-Prolog,则可以使用DCG增强解析。例如

:- use_module(library(dcg/basics)).
:- use_module(library(dcg/high_order)).

parse_3by3data(Rl, FQty, Costs) -->
    a_line_of_numbers(Rl),
    a_line_of_numbers(FQty),
    sequence(a_line_of_numbers,Costs).

a_line_of_numbers(L) -->
    whites,
    sequence(number,whites,L),
    whites, "\n".

parse_3by3data // 3是一种语法产生形式,您可以直接在文件中使用带有短语/ from_file或字符串...的带有短语/ 3的语法。即

test :-
    phrase(parse_3by3data(Rl, FQty, Costs),
` 3   4
  10 60 30 40
  50 30 60
  2 4  5  6
  7 8  9  4
  1 2  4  6
`), writeln(parse_3by3data(Rl, FQty, Costs)).