List 列表和上的参数没有充分实例化
我试图约束列表的总和,但我的代码在List 列表和上的参数没有充分实例化,list,prolog,instantiation,swi-prolog,clpfd,List,Prolog,Instantiation,Swi Prolog,Clpfd,我试图约束列表的总和,但我的代码在label()处失败 .pl: 有什么想法吗 编辑: 运行调试器:,我认为错误在label()中,此时: finite_domain(Var) :- ( fd_get(Var, Dom, _) -> ( domain_infimum(Dom, n(_)), domain_supremum(Dom, n(_)) -> true ; instantiation_error(Va
label()
处失败
.pl:
有什么想法吗
编辑: 运行调试器:,我认为错误在
label()
中,此时:
finite_domain(Var) :-
( fd_get(Var, Dom, _) ->
( domain_infimum(Dom, n(_)), domain_supremum(Dom, n(_)) -> true
; instantiation_error(Var)
)
; integer(Var) -> true
; must_be(integer, Var)
).
使用图形调试器单步执行代码:
?- gtrace, solve(L, 5).
正如您将看到的,label/1
与此错误没有任何关系
使用CLP(FD)约束,而不是sum\u list/2
:它可以在各个方向工作,让您看到查询的答案
我建议你退后一步,认真考虑你在这里做什么。< /P>
例如,为什么要将副作用(write/1
)与纯代码混用?专注于对问题的清晰的声明性描述,让顶层为您做报告
此外,如此频繁地需要额外的逻辑谓词(如(==)/2
)也是非常罕见的。例如,写:
sublists_below_center(_, _, Dim, End) :-
End #= Dim - 2.
在不使用额外的逻辑语言元素的情况下,使参数之间的关系完全清楚
使用flatte/2
几乎总是一个坏主意,通常表明数据结构设计中存在问题。使用append/2
删除一级嵌套
如果已经导入CLP(FD)库,为什么还要使用基本算术?在整个过程中使用(#=)/2
等
此外,谓词名称表明您对问题的思考过于迫切。专注于问题解决方案的纯声明性描述,Prolog将为您完成其余的工作。避免使用命令式名称。取而代之的是,使用描述在什么条件下保持什么的名称。使用图形调试器逐步完成代码:
?- gtrace, solve(L, 5).
正如您将看到的,label/1
与此错误没有任何关系
使用CLP(FD)约束,而不是sum\u list/2
:它可以在各个方向工作,让您看到查询的答案
我建议你退后一步,认真考虑你在这里做什么。< /P>
例如,为什么要将副作用(write/1
)与纯代码混用?专注于对问题的清晰的声明性描述,让顶层为您做报告
此外,如此频繁地需要额外的逻辑谓词(如(==)/2
)也是非常罕见的。例如,写:
sublists_below_center(_, _, Dim, End) :-
End #= Dim - 2.
在不使用额外的逻辑语言元素的情况下,使参数之间的关系完全清楚
使用flatte/2
几乎总是一个坏主意,通常表明数据结构设计中存在问题。使用append/2
删除一级嵌套
如果已经导入CLP(FD)库,为什么还要使用基本算术?在整个过程中使用(#=)/2
等
此外,谓词名称表明您对问题的思考过于迫切。专注于问题解决方案的纯声明性描述,Prolog将为您完成其余的工作。避免使用命令式名称。取而代之的是,使用描述在什么条件下保持什么的名称。一种方法是运行跟踪,然后重试查询。键入
跟踪。
然后执行查询。每个步骤都将详细显示,直到找到问题为止。它会指出问题所在。谢谢潜伏者,从现在起我会记住这一点!这是一个方便的工具。有时你需要提供一个非常简单的例子,但失败了,或者你可以在那里一整天的跟踪!一种方法是运行跟踪,然后再次尝试查询。键入跟踪。
然后执行查询。每个步骤都将详细显示,直到找到问题为止。它会指出问题所在。谢谢潜伏者,从现在起我会记住这一点!这是一个方便的工具。有时你需要提供一个非常简单的例子,但失败了,或者你可以在那里一整天的跟踪!