我有一系列的关系,我希望像我一样通过记录匹配来遍历它们。比如说,我们在支持以下库函数进行图形操作的系统中有以下bizzare情况:
image(raw).
image(png).
image(bitmap).
image(tiff).
conversion(tiff2bitmap, tiff, bitmap).
conversion(bitmap2png, bitmap, png).
conversion(png2raw, png, raw).
conversion(raw2bitmap, raw, bitmap).
conversion(png2tiff, png, tiff).
operation(crop, raw, raw).
因此,在上面的示例中,如果我们想裁剪一个 tiff ,您必须执行以下操作:
例如,我可以坐在Prolog REPL上,首先询问将tiff转换为位图的操作:
?- conversion(OP1, tiff, F1).
OP1 = tiff2bitmap,
F1 = bitmap .
?- conversion(OP2, F1, F2).
OP2 = tiff2bitmap,
F1 = tiff,
F2 = bitmap ;
OP2 = bitmap2png,
F1 = bitmap,
F2 = png
... and so on
我希望能够在Prolog中遵循以下逻辑,但我不知道如何处理这个问题。我想我需要使用递归规则和累加器。我们可以使用以下方法计算如何裁剪tiff。我可以像这样手动解决上述问题:
/* the op is op in operation(op, x, x) */
conversions(Op, In, Steps) :-
operation(Op, In, Out); /* no conversions necessary */
conversion(C1, O1, O2),/* switch the incoming/outgoing to */
conversion(C2, O2, O3), /* match successive conversions */
conversion(C3, O3, O4), /* A->B, B->C, C->D */
/* adding the matches C1-C3 to steps */
我更倾向于使用累加器和递归规则自动处理它,但我不知道如何处理它。
答案 0 :(得分:2)
在larsmans提到“路径搜索”后,我搜索并找到了“TekTips question ”。由此看来,以下似乎有效:
image(raw).
image(png).
image(bitmap).
image(tiff).
conversion(tiff2bitmap, tiff, bitmap).
conversion(bitmap2png, bitmap, png).
conversion(png2raw, png, raw).
conversion(raw2bitmap, raw, bitmap).
conversion(png2tiff, png, tiff).
operation(crop, raw, raw).
sconversions(End, A, End, [Conv]) :-
conversion(Conv, A, End).
sconversions(End, A, B, Ops) :-
conversion(X, A, C),
sconversions(End, C, B, TailOps),
Ops = [X|TailOps].
convert(Op, A, Path) :-
operation(Op, In, _),
sconversions(In, A, In, Path).
convertKeep(Op, A, Path) :-
operation(Op, In, Out),
sconversions(In, A, In, CPath),
sconversions(A, Out, A, RPath), /* backward */
append(CPath, RPath, Path).
转换无视输出格式:
?- convert(crop, tiff, Ops).
Ops = [tiff2bitmap, bitmap2png, png2raw, crop]
以下显示了转化次数: ? - convertKeep(crop,tiff,Ops)。 Ops = [tiff2bitmap,bitmap2png,png2raw,crop,raw2bitmap,bitmap2png,png2tiff]
我是Prolog的新手,访客最好不要学习larsmans的回答。
答案 1 :(得分:1)
在描述列表时,请始终考虑使用DCG。在您的情况下,您只需要以下内容:
conversions(S, S) --> [].
conversions(S0, S) -->
{ conversion(Op, S0, S1) },
[Op],
conversions(S1, S).
现在,您可以使用迭代深化来详尽地尝试越来越长的操作列表,直到达到所需的目标状态。例如,要从tiff
转到raw
:
?- length(Ops, _), phrase(conversions(tiff, raw), Ops).
Ops = [tiff2bitmap, bitmap2png, png2raw] .