2

私は一連の関係を持っており、進行中に一致を記録してグラフのようにトラバースしたいと考えています。たとえば、グラフィカルな操作のために次のライブラリ関数をサポートするシステムで、次の奇妙な状況があるとします。

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を切り取りたい場合は、次のようにする必要があります。

  • tiff をビットマップに変換する
  • ビットマップをpngに変換します
  • PNGを生に変換します
  • トリミング操作を使用する
  • raw をビットマップに変換する
  • ビットマップをpngに変換します
  • png を 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 */

アキュムレータと再帰ルールを使用してこれを自動的に処理したいのですが、これにアプローチする方法がわかりません。

4

2 に答える 2

2

larsmansが「パス検索」について言及した後、私は「TekTips質問」を検索して見つけました。このことから、次のことが機能しているようです。

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の答えを研究するほうがよいでしょう。

于 2012-04-22T12:28:25.330 に答える
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] .
于 2014-10-21T21:26:25.377 に答える