【问题标题】:Is it possible to preserve variable names when writing and reading term programatically?以编程方式编写和读取术语时是否可以保留变量名称?
【发布时间】:2019-06-18 18:12:38
【问题描述】:

我正在尝试编写一个 SWI-Prolog 谓词,它将 numbervars/3 应用于术语的匿名变量,但保留用户提供的非匿名变量的名称。我最终计划为term_expansion(或类似的东西)添加某种钩子。

所需输出示例:

    ?- TestList=[X,Y,Z,_,_].
       > TestList=[X,Y,Z,A,B].

This answer 到问题Converting Terms to Atoms preserving variable names in YAP prolog 展示了如何使用read_term 将术语中使用的变量的名称作为原子获得。这个列表(形式为 [X='X',Y='Y',...])不包含匿名变量,与term_variables 获得的变量列表不同,这使得匿名变量的隔离相当简单。

但是,如果仅将其应用于直接从终端读取的术语,则此功能的有用性会受到一定限制。我注意到答案中的所有示例都涉及该术语的直接用户输入。 是否有可能获取(作为原子)通过用户直接输入获得的术语的变量名称?也就是说,是否有某种方法可以“编写”一个术语(保留变量名)到一些不可见的流,然后像从终端输入一样“读取”它?

另外...也许这更像是一种 LaTeX 式的思路,但是在 Prolog 扩展/尝试将它们统一为变量之前,是否有某种方法可以将变量“包装”在单引号内(从而将它们原子化) , 最终结果是它们被视为以大写字母开头的原子而不是变量?

【问题讨论】:

  • write_term 不够好?
  • 如果您想从终端以外的地方读取术语,您可以使用read_term/3 在第一个位置提供流。您能否详细说明为什么您需要此功能?如果我们对您正在尝试做的事情有更多了解,那么您可能要从另一个角度更直接地解决您要解决的真正问题。
  • 糟糕,我链接到了错误的问题和答案。我刚刚纠正了它。很抱歉,如果这造成任何混乱

标签: variables io stream prolog iso-prolog


【解决方案1】:

是否可以(作为原子)获取不是通过直接用户输入获得的术语的变量名称?

如果你想从源文件中获取变量名,你应该从那里读取它们。

使用术语扩展的最简单方法。

解决方案:

read_term_from_atom(+Atom, -Term, +Options)

使用read_term/3Atom 读取下一个术语。

Atom 是原子或字符串对象。

Atom 不需要以句号结尾。

使用Atom 作为read_term/2 的输入,使用选项variable_names 并返回Term 中的读取项和variable_names(Bindings) 中的变量绑定。

BindingsName = Var 对的列表,因此可以访问实际的变量名。另见read_term/2

如果Atom 没有有效的语法,则会引发syntax_error 异常。

write_term( Term ) :-
  numbervars(Term, 0, End),
  write_canonical(Term), nl.

【讨论】:

  • 谢谢,这在从原子工作时非常有效。但是,如果我想要变量名称的术语不是原子,而是(例如)复合函子、列表或独立变量怎么办?这些都可以通过read_term 和直接用户输入来处理,正如我链接的答案所展示的那样......但是有没有办法直接将write_term 的输出重定向到read_term 等,without 将变量解析为变量/而不用匿名替换它们?我了解如何使用read_term_from_atom,但我正在寻找一种read_term_from_termread_term_verbatim...
  • 可能你只需要portray_clause/1。从AB...swi-prolog.org/pldoc/man?predicate=portray_clause/2
【解决方案2】:

您可以使用 ISO 核心标准 variable_names/1 读写选项。下面是一些示例代码,用于替换变量名映射中的匿名变量:

% replace_anon(+Map, +Map, -Map)
replace_anon([_=V|M], S, ['_'=V|N]) :- member(_=W, S), W==V, !, 
   replace_anon(M, S, N).
replace_anon([A=V|M], S, [A=V|N]) :- 
   replace_anon(M, S, N).
replace_anon([], _, []). 

variable_names/1 是 ISO 核心标准。它始终是一个读取选项。然后它也成为了一个写入选项。另见:https://www.complang.tuwien.ac.at/ulrich/iso-prolog/WDCor3

这是一个运行示例:

Welcome to SWI-Prolog (threaded, 64 bits, version 7.7.25)

?- read_term(X,[variable_names(M),singletons(S)]), 
   replace_anon(M,S,N), 
   write_term(X,[variable_names(N)]).
|: p(X,Y,X).
p(X,_,X)

不推荐使用旧的 numbervars/3,因为它与属性变量不兼容。例如,在存在 CLP(FD) 的情况下,您不能使用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-03
    • 1970-01-01
    • 2015-03-11
    • 1970-01-01
    • 2018-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多