读取文件,然后将其转换为序言中的列表

时间:2019-03-19 19:10:53

标签: prolog

在序言中查找将file.txt转换为列表的代码,如下所示:

3  3
10 80 30
40 50 20 10
2  3  5  6
6  2  6  9
4  6  8  1

List1=[3,3]
List2=[10,80,30]
List3=[40,50,20,10]
Cost=[[2,3,5,6],[6,2,6,9],[4,6,8,1]]

1 个答案:

答案 0 :(得分:1)

完整代码:

:- use_module(library(dcg/basics), except([eos/2])).

lists(Input_path) :-
    DCG = read_lists(Lists),
    phrase_from_file(DCG,Input_path), !,
    Lists = [List1,List2,List3,List4,List5,List6],
    format('List1=~w~n',[List1]),
    format('List2=~w~n',[List2]),
    format('List3=~w~n',[List3]),
    format('Cost=[~w,~w,~w]~n',[List4,List5,List6]).

eos([], []).

read_lists([]) --> call(eos).
read_lists([List|Lists]) -->
    read_list(List),
    (
        "\n"
    |
        []
    ),
    read_lists(Lists).
read_lists([]) --> [].

read_list([Item|Items]) -->
    number(Item),
    whites,
    read_list(Items).
read_list([]) --> [].

示例运行:

?- lists("C:/data.txt").
List1=[3,3]
List2=[10,80,30]
List3=[40,50,20,1]
Cost=[[2,3,5,6],[6,2,6,9],[4,6,8,1]]
true.

代码说明

虽然列表解析可以通过递归代码完成,并手动保存和传递state变量,但使用确定性子句语法(DCG)则更容易。

进行DCG时,会预先编写谓词库。使用SWI-Prolog时,DCG最受欢迎的库是DCG/basics

这行代码引入了库。但是eos / 2会导致错误,因此我将其排除在外并手动将其添加到代码中。

:- use_module(library(dcg/basics), except([eos/2])).

DCG是隐藏两个状态变量的子句,可以使用listing/1看到它们。

所有使用-->而不是:-的代码都是DCG。

使用DCG的常见方法是与phrase/2一起使用,但是从文件中读取数据然后使用词组是如此普遍,因此有一个更好的谓词可以使用phrase_from_file/2

该库中DCG中的两个子句为number//1whites//0

eos用于end_of_steam,在基本情况下用于read_lists//1

format/2用于写出结果。

其余为标准的简单Prolog。