【问题标题】:fragmenting data from text file into list of facts to prolog file将文本文件中的数据分割成事实列表到 prolog 文件
【发布时间】:2016-04-23 09:52:00
【问题描述】:

我想将数据文件分成诸如functor(arg1, arg2, ..., argN) 之类的事实列表,其中函子的名称是 大写 行,参数是后面的 小写 行他们, 随后,新子句将保存在执行时创建的 prolog 文件中

文件.txt

FUNCTOR1
arg1 
arg2
FUNCTOR2
arg1
arg2
arg3
FUNCTOR3
arg1
arg2
arg3
arg4

结果:

?- split_data_to_facts('file.txt',List,'file.pl').
List = ['functor1(arg1,arg2)','functor2(arg1,arg2,arg3)','functor3(arg1,arg2,arg3,arg4)'].

文件.pl

“。”将作为最后一个附加

functor1(arg1,arg2).        
functor2(arg1,arg2,arg3).
functor3(arg1,arg2,arg3,arg4).

构建和编译new prolog 文件file.pl:

?- functor2(X,Y,Z).
X=arg1,
Y=arg2,
Z=arg3;
yes

【问题讨论】:

  • 你有没有尝试过?
  • 我尝试解析文件并将数据放入列表
  • 你在哪里卡住了?您可以使用=../2 运算符。例如,X =.. [functor, a, b]X = functor(a, b)
  • 列表类似于 :List=['FUNCTOR1','arg1','arg2','FUNCTOR2','arg1','arg2','arg3'|...]跨度>
  • 您需要先拆分您的列表。您应该能够编写一些非常简单的列表处理代码来做到这一点。或者,在从文件中读取它时将其拆分,以便函子是分开的。

标签: file parsing io prolog sicstus-prolog


【解决方案1】:

假设内置的 read_line_to_codes/2 可用:那么您可以应用 lookahead 一行:

process_file(Path) :-
  open(Path, read, In),
  read_line_to_codes(In, Line1),
  read_line_to_codes(In, Line2), % assume not empty
  process_lines(Line2, [Line1], In, Facts),
  maplist(writeln, Facts).  % just for test

process_lines(end_of_file, LastFactDef, In, [LastFact]) :-
  lines_fact(LastFactDef, LastFact),
  close(In).
process_lines([U|Us], LastFactDef, In, [LastFact|Facts]) :-
  upper_lower(U, _),
  lines_fact(LastFactDef, LastFact),
  read_line_to_codes(In, Line),
  process_lines(Line, [[U|Us]], In, Facts).
process_lines(Last, Lines, In, Facts) :-
  read_line_to_codes(In, Line),
  process_lines(Line, [Last|Lines], In, Facts).

lines_fact(Lines, Fact) :-
  reverse(Lines, [FunctorUpper|ArgCodes]),
  maplist(make_lower, FunctorUpper, FunctorCodes),
  maplist(atom_codes, [Functor|Args], [FunctorCodes|ArgCodes]),
  Fact =.. [Functor|Args].

% if uppercase get lowercase
upper_lower(U, L) :-
  between(0'A, 0'Z, U), L is 0'a + U - 0'A.

make_lower(C, L) :- upper_lower(C, L) ; L = C.

在 SWI-Prolog 中运行测试(默认情况下,我们有可用的 read_line_to_codes/2 和 between/3):

?- process_file('/home/carlo/test/file.txt').
functor1(arg1 ,arg2)
functor2(arg1,arg2,arg3)
functor3(arg1,arg2,arg3,arg4)
true 

【讨论】:

  • 谢谢,但你能解释一下 Args 是如何附加到她的函子上的吗?
  • 不以大写开头的每一行都被“推送”到 LastFactDef。然后 =.. (所谓的 univ) 安排函子和参数
  • 抱歉,是哪一行,是 process_lines/4 吗?为什么会出现这个 [[U|Us]](示例)
  • process_lines/4 的第一个参数是字符代码列表。为了测试第一个字符,列表在头部被“分解”,并在被推送时“重新组合”,稍后用作仿函数
  • 你能解释一下这个 [[X|Xs]] 吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-30
  • 1970-01-01
  • 1970-01-01
  • 2013-11-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多