如果我想动态管理数据或事实,我有几个主要选择,例如:
>在Prolog,OR中将数据作为断言进行管理
>从Prolog,OR到数据库的接口
>可能两者兼而有之
如果我将事实作为Prolog中的断言进行管理,我也有一个代表这些事实的最佳方式的问题.假设我有一个名字,姓氏和年龄的人.我可以断言:
person(first_name(_),last_name(_),age(_)).
或隐含假设人的属性是什么:
person(_,_,_). % first name,last name,age
如果我想将一个人与其他人联系起来,我真的需要一个人的钥匙.所以我可能倾向于断言一个人:
person(id(_),...). % Maintain id as a uniq person key; or done implicitly as above
当然,现在我正在使我的Prolog断言看起来像关系数据库表条目.这让我想知道我是否采取了错误的方法并使事实的表现过于复杂化.
实际上,我的问题是:在Prolog中管理中到复杂数据时是否需要考虑一些最佳实践?命名约定是它的一小部分.我读过像Prolog中的assert / retract一样低效的位.所以我也想知道如何处理数据组织本身,比如什么时候采用外部sql数据库而不是Prolog-only表示.
附录
我认为,由于关系数据库使用它们的原因,在关系数据库中使用记录密钥是可取的.这意味着必须保持密钥.对于每种情况,在Prolog中手动(显式)执行此操作似乎很麻烦,那么这通常如何完成?或者我的假设是正确的?
解决方法
id_fname_lname_age(_,_).
这明确表示参数是什么而不需要任何其他结构.
在我看来,命名谓词的一个好的经验法则是按照它们出现的顺序描述参数,使用以下划线分隔的声明性名称.
编辑:关于你的其他问题:与一个很好的声明性编程风格相比,assertz / 1很慢(并且还有许多其他缺点),它简单地在不需要对子句数据库进行任何修改的谓词之间传递参数.当你真的需要断言其他事实,因为你正在使用像关系数据库系统这样的Prolog,那么assertz / 1是一种方法(其他选项在这里的其他答案中提到),并且可能在效率上与任何其他选项相当许多使用场景的关系数据库系统.如前所述,一些现代Prolog系统对所有参数执行即时索引,因此您无需显式声明任何“键”.