在prolog中调试一段代码

在prolog中调试一段代码,prolog,Prolog,Prolog中有一段代码,用于将txt文件转换为4个列表(3个1D_列表,每行一个,最后一个是2D_列表,其余行每行一个子列表) 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 lin

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

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]、[成本2]、成本)

由于错误地将变量成本1和循环终止的替代条款(在EOF时)与流
Str
[]
匹配,因此无法工作

关于代码风格的说明。与任何其他语言一样,在Prolog中,在可重用的“子例程”中分组重复的公共功能是有价值的

read\u-line\u-to\u-string、split\u-string、maplist(atom\u-number)
的组合经常被使用。用它们来做一个服务谓词

如果您使用SWI Prolog,则可以使用DCGs增强解析

:- 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是一种语法产品,您可以直接在文件上使用,其中包含来自_文件的短语_,或包含短语/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)).

write()
看起来很奇怪。非常感谢。它工作得很好。我直接在“3 4 10 60…”中使用文件,它确实工作。测试如下:测试(文件):-phrase(解析3by3data(Rl,FQty,WQty,Costs),file),writeln(解析3by3data(Rl,FQty,WQty,Costs)).这段代码中有什么问题吗?非常感谢。它工作得很好。我直接为“3 4 10 60…”使用文件,它不工作。测试如下:测试(文件):-短语(解析3by3data(Rl,FQty,WQty,Costs),file),writeln(解析3by3data(Rl,FQty,WQty,Costs))。这段代码中有问题吗?