Reputation: 61
Looking for codes in prolog to convert a file.txt to lists as following:
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]]
Upvotes: 2
Views: 599
Reputation: 24976
Complete code:
:- 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([]) --> [].
Example run:
?- 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.
Explanation of code
While parsing of list can be done with recursive code and keeping and passing the state variables manually, doing it with Definitive Clause Grammars (DCG) is easier.
When doing DCG there are prewritten libraries of predicates. The most popular library for DCGs when using SWI-Prolog is DCG/basics.
This line of code brings in the library. However eos/2 causes an error so I exclude it and add it in the code manually.
:- use_module(library(dcg/basics), except([eos/2])).
DCG are clauses that hide two state variables that can be seen by using listing/1.
All of the code that uses -->
instead of :-
are DCG.
A common way to use DCGs is with phrase/2 but reading data from a file and then using phrase is so common there is a better predicate to use phrase_from_file/2.
The two clauses in the DCG from the library are number//1
and whites//0
.
eos
is for end_of_steam and is used in the base case for read_lists//1
format/2 is used to write out the result.
The rest is standard simple Prolog.
Upvotes: 2