简体   繁体   English

Prolog,将术语转换为列表

[英]Prolog, converting term into a list

Hello I have a predicate that return's example equalisation for given list 您好,我有一个谓词,即返回给定列表的示例均衡

equalisation([1,2,3,4,12],L).
L = (1=2-3* (4/12)) 

now I want to change this result into a list like this: 现在我想将此结果更改为这样的列表:

L = [1,=,2,-,3,*,4,/,12]

How can I do that? 我怎样才能做到这一点?

The simplest solution would be to traverse a term creating a list of small lists, and then to flatten everything. 最简单的解决方案是遍历创建小列表列表的术语,然后将所有内容展平。 However, the simplest solution is not the most elegant one - quoting the SWI Prolog flatten/2 manual : 但是,最简单的解决方案不是最优雅的解决方案-引用SWI Prolog flatten / 2手册

Ending up needing flatten/3 often indicates, like append/3 for appending two lists, a bad design. 最终需要flatten / 3常常表明,例如append / 3用于附加两个列表,这表明设计不良。 Efficient code that generates lists from generated small lists must use difference lists, often possible through grammar rules for optimal readability. 从生成的小列表生成列表的高效代码必须使用差异列表,通常可以通过语法规则实现差异列表,以实现最佳可读性。

So here is an alternative solution using difference lists: 因此,这是使用差异列表的替代解决方案:

t2l(Term, List) :- t2l_(Term, List-X), X = [].

t2l_(Term, [F|X]-X) :- Term =.. [F], !.
t2l_(Term, L1-L4) :- Term =.. [F, A1, A2], 
                     t2l_(A1, L1-L2), 
                     L2 = [F|L3], 
                     t2l_(A2, L3-L4).

Clearly, the current solution works only for binary operations. 显然,当前解决方案仅适用于二进制操作。 If operations with an arbitrary number of arguments are allowed, then another traversal of the arguments will be required. 如果允许使用任意数量的参数进行运算,则将需要对参数进行另一遍历。

Check out how the (=..)/2 operator works. 查看(=..)/2运算符的工作方式。

And if you wanna check that expressions are equal use (=:=)/2 instead of (=)/2 . 如果要检查表达式是否相等,请使用(=:=)/2而不是(=)/2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM