如何识别Prolog术语的浪费表示 [英] How to identify wasteful representations of Prolog terms

查看:101
本文介绍了如何识别Prolog术语的浪费表示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是Prolog谓词,可以帮助显示Prolog术语的浪费表示形式?






补充



在较早的Prolog SO答案中,IIRC由






干净还是默认表示



来自Prolog的力量 Markus Triska



用Prolog术语表示数据时,请问自己以下问题:


我可以与每个组件的最外层函子和对偶性区别开来吗?

如果成立,则您的表示称为 clean 。如果无法通过最外层的函子和Arity区分元素,则表示形式为 defaulty ,即结合了 default和 faulty的文字游戏。这是因为对数据进行推理会需要一个 默认情况下,如果其他所有方法均失败,则将使用该情况。另外,这样的表示防止了参数索引,并且由于这个缺点被认为是有缺陷的。始终要避免使用默认表示!

解决方案

请参阅以下内容的最后一部分:



https://stackoverflow.com/a/42722823/1613573



它使用 write_canonical / 1 来显示术语的 canonical 表示。



该谓词在学习Prolog时非常有用,有助于清除对于初学者来说常见的一些误解。例如,请参阅最近有关连字符的问题,该问题也可能会有所帮助。



请注意,在SWI中,输出通常会偏离规范的Prolog语法,因此在解释Prolog语法时我不会使用SWI。


What is the Prolog predicate that helps to show wasteful representations of Prolog terms?


Supplement

In a aside of an earlier Prolog SO answer, IIRC by mat, it used a Prolog predicate to analyze a Prolog term and show how it was overly complicated.

Specifically for a term like

[op(add),[[number(0)],[op(add),[[number(1)],[number(1)]]]]]

it revealed that this has to many [].

I have searched my Prolog questions and looked at the answers twice and still can't find it. I also recall that it was not in SWI-Prolog but in another Prolog so instead of installing the other Prolog I was able to use the predicate with an online version of Prolog.

If you read along in the comments you will see that mat identified the post I was seeking.


What I was seeking

I have one final note on the choice of representation. Please try out the following, using for example GNU Prolog or any other conforming Prolog system:

| ?- write_canonical([op(add),[Left,Right]]). 
'.'(op(add),'.'('.'(_18,'.'(_19,[])),[]))

This shows that this is a rather wasteful representation, and at the same time prevents uniform treatment of all expressions you generate, combining several disadvantages.

You can make this more compact for example using Left+Right, or make all terms uniformly available using for example op_arguments(add, [Left,Right]), op_arguments(number, [1]) etc.


Evolution of a Prolog data structure

If you don't know it already the question is related to writing a term rewriting system in Prolog that does symbolic math and I am mostly concentrating on simplification rewrites at present.

Most people only see math expressions in a natural representation

x + 0 + sin(y)

and computer programmers realize that most programming languages have to parse the math expression and convert it into an AST before using

add(add(X,0),sin(Y))

but most programming languages can not work with the AST as written above and have to create data structures See: Compiler/lexical analyzer, Compiler/syntax analyzer, Compiler/AST interpreter

Now if you have ever done more than dipped your toe in the water when learning about Prolog you will have come across Program 3.30 Derivative rules, which is included in this, but the person did not give attribution.

If you try and roll your own code to do symbolic math with Prolog you might try using is/2 but quickly find that doesn't work and then find that Prolog can read the following as compound terms

 add(add(X,0),sin(Y))

This starts to work until you need to access the name of the functor and find functor/3 but then we are getting back to having to parse the input, however as noted by mat and in "The Art of Prolog" if one were to make the name of the structure accessible

 op(add,(op(add,X,0),op(sin,Y)))

now one can access not only the terms of the expression but also the operator in a Prolog friendly way.

If it were not for the aside mat made the code would still be using the nested list data structure and now is being converted to use the compound terms that expose the name of the structure. I wonder if there is a common phrase to describe that, if not there should be one.

Anyway the new simpler data structure worked on the first set of test, now to see if it holds up as the project is further developed.


Try it for yourself online

Using GNU Prolog at tutorialspoint.com enter

:- initialization(main).
main :- write_canonical([op(add),[Left,Right]]).

then click Execute and look at the output

sh-4.3$ gprolog --consult  file main.pg  
GNU Prolog 1.4.4 (64 bits)  
Compiled Aug 16 2014, 23:07:54 with gcc  
By Daniel Diaz  
Copyright (C) 1999-2013 Daniel Diaz  
compiling /home/cg/root/main.pg for byte code...  
/home/cg/root/main.pg:2: warning: singleton variables [Left,Right] for main/0  
/home/cg/root/main.pg compiled, 2 lines read - 524 bytes written, 9 ms  
'.'(op(add),'.'('.'(_39,'.'(_41,[])),[]))| ?-  


Clean vs. defaulty representations

From The Power of Prolog by Markus Triska

When representing data with Prolog terms, ask yourself the following question:

Can I distinguish the kind of each component from its outermost functor and arity?

If this holds, your representation is called clean. If you cannot distinguish the elements by their outermost functor and arity, your representation is called defaulty, a wordplay combining "default" and "faulty". This is because reasoning about your data will need a "default case", which is applied if everything else fails. In addition, such a representation prevents argument indexing, and is considered faulty due to this shortcoming. Always aim to avoid defaulty representations! Aim for cleaner representations instead.

解决方案

Please see the last part of:

https://stackoverflow.com/a/42722823/1613573

It uses write_canonical/1 to display the canonical representation of a term.

This predicate is very useful when learning Prolog and helps to clear several misconceptions that are typical for beginners. See for example the recent question about hyphens, where it would have helped too.

Note that in SWI, the output deviates from canonical Prolog syntax in general, so I am not using SWI when explaining Prolog syntax.

这篇关于如何识别Prolog术语的浪费表示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆