Prolog多米诺链校验与生成谓词异常问题求助
多米诺链Prolog谓词调试求助
问题背景
我正在Exercism上学习Prolog,做多米诺链习题,不想直接找答案,只需要调试方向的帮助。
具体问题
is_chain/1生成非法结果:
原本我把校验逻辑拆成了is_loop(检查首尾衔接)和is_chain_no_loop(检查内部衔接)两个部分,后来改成了递归版本。但查询is_chain(R)时,会跑出不符合规则的链——比如有的结果里前后多米诺根本接不上,首尾也不匹配。chain/2与is_chain/1逻辑矛盾:
我写的chain/2是用来从多米诺堆生成合法链的,但查询chain([(1,1)], R)返回false,单独调用is_chain([(1,1)])却返回true。我用的是SWISH在线SWI-Prolog环境。
调试方向建议
针对is_chain/1的问题
- 先查递归的边界条件:空链、单多米诺的处理逻辑是不是真的符合题目要求?比如单多米诺是否被判定为合法链?
- 检查递归步的衔接判断:每次递归时,有没有确保当前多米诺的尾和下一个多米诺的头(或者翻转后的头)能正确匹配?别漏了多米诺可以翻转使用的情况——
(A,B)和(B,A)是等价的。 - 如果
is_chain/1是用来生成所有合法链的,那得确认递归过程中有没有跟踪已使用的多米诺?要是没做这个约束,很可能会生成重复使用多米诺或者衔接错误的结果。
针对chain/2的矛盾问题
- 对比两个谓词的边界处理:看看
chain/2处理单多米诺输入时,是不是加了额外约束(比如强制要求成环?),而is_chain/1没有? - 检查
chain/2的调用逻辑:是不是在生成结果后,调用is_chain/1时多了不必要的过滤?或者生成过程中就没正确生成单多米诺的情况? - 用
trace命令跟踪执行:在SWISH里跑trace, chain([(1,1)], R).,一步步看哪一步导致了失败,再对比trace, is_chain([(1,1)]).的执行轨迹,找出两者的差异点。
通用调试技巧
- 拆成小谓词逐个测试:比如先写个
can_connect/2来判断两个多米诺能不能衔接,单独测试这个谓词的各种情况,确保逻辑没问题。 - 用具体用例验证分支:分别测试非环链(比如
[(1,2),(2,3)])、环链(比如[(1,2),(2,3),(3,1)])、单多米诺这几种情况,看is_chain/1的返回是否符合预期。
内容的提问来源于stack exchange,提问作者hr0m
相关产品推荐
相关产品推荐

