2016-02-17 28 views
4

在Prolog玩弄鏡頭。鏡頭是一種顯微鏡,可以放大結構並以功能方式進行一些讀取或寫入。基本上我的出發點是setter和getter方法聲明中的Prolog以下建模:通過DCG在Prolog的鏡頭,可能與否?

消氣:只是一個<closure>
稱爲call(<closure>, X, Y), 這將從X檢索值Y

聲明二傳手:同樣<closure>但有不同的元數使用,
稱爲call(<closure>, X, Y, Z),這將給予新的Z一個新值Y更新X

我很快就找到了一個鏡頭合成操作符@的定義,它可以用來將兩個鏡頭合併爲一個新鏡頭,只是基於它們的關閉。附錄中有一個例子和一個定義。但根據這article鏡頭可以被製作成簡單的組成。

在我看來,當某些東西是成分時,它可以很容易地通過DCG建模。我可以爲吸氣做法如下,但我並沒有想出一個辦法做到這一點的聲明二傳手,以及:

/* Getter composition as DCG */ 
@(C1, C2) --> 
    call(C1), 
    call(C2). 

我怎麼會在DCG二傳手組合模型?這是可能的,也許改變了吸氣劑和聲明設定器如何建模的初始假設,以便結果僅僅是合成的?

此致

附錄: 下面是一些setter和getter的示例:

/* getter */ 
back(bicycle(X, _), X). 
front(bicycle(_, Y), Y). 
circumference(wheel(X, _), X). 
spokes(wheel(_, Y), Y). 

/* setter */ 
back(bicycle(_, Y), X, bicycle(X, Y)). 
front(bicycle(X, _), Y, bicycle(X, Y)). 
circumference(wheel(_, Y), X, wheel(X, Y)). 
spokes(wheel(X, _), Y, wheel(X, Y)). 

這裏是透鏡組合物的造型:

:- op(600, xfy, @). 

/* getter composition */ 
@(C1, C2, X, Y) :- 
    call(C1, X, H), 
    call(C2, H, Y). 

/* setter composition */ 
@(C1, C2, X, Y, Z) :- 
    call(C1, X, H), 
    call(C2, H, Y, J), 
    call(C1, X, J, Z). 

下面是一些示例運行:

Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.16) 
Copyright (c) 1990-2015 University of Amsterdam, VU Amsterdam 

?- call([email protected], bicycle(wheel(1330, 12), wheel(1440, 16)), X). 
X = 16. 

6 ?- call([email protected], bicycle(wheel(1330, 12), wheel(1440, 16)), X). 
X = 1330. 

7 ?- call([email protected], bicycle(wheel(1330, 12), wheel(1440, 16)), 1420, X). 
X = bicycle(wheel(1330, 12), wheel(1420, 16)). 
+3

哇,是的,標籤鏡頭很多! –

回答

0

有一種解決方案具有更進一步的間接性,但也具有以某種方式預編譯訪問路徑的潛力。我們再次將訪問路徑視爲閉包,但這次它們修改了連續函數。有兩種類型的延續:

消氣繼續:
- 返回之前變換值。
聲明性安裝程序繼續:
- 在更新值之前將其轉換爲附加參數。

訪問路徑元素現在轉換這兩個連續,以提供新的延續。訪問路徑元素轉換是組合性的,由此首先應用內部訪問元素。

附錄中給出了一些示例延續,然後我們可以通過DCG對訪問元素的組合進行建模,如下所示。注意DCG正文中的順序,這反映了前面提到的訪問元素順序。

/* composition */ 
@(C1, C2) :- 
    call(C2), 
    call(C1). 

再見

附錄: 這裏有一些轉換器定義:

/* transformer construction */ 
back(F, back(F)). 
front(F, front(F)). 
circumference(F, circumference(F)). 
spokes(F, spokes(F)). 

/* getter transformer */ 
back(F, bicycle(X, _), Y) :- call(F,X,Y). 
front(F, bicycle(_, X), Y) :- call(F,X,Y). 
circumference(F, wheel(X, _), Y) :- call(F,X,Y). 
spokes(F, wheel(_, X), Y) :- call(F,X,Y). 

/* setter transformer */ 
back(F, bicycle(X, Y), Z, bicycle(T, Y)) :- call(F,X,Z,T). 
front(F, bicycle(X, Y), Z, bicycle(X, T)) :- call(F,Y,Z,T). 
circumference(F, wheel(X, Y), Z, wheel(T, Y)) :- call(F,X,Z,T). 
spokes(F, wheel(X, Y), Z, wheel(X, T)) :- call(F,Y,Z,T). 

這裏是鏡片組成,有的停止變壓器:

:- op(600, xfy, @). 

/* composition */ 
@(C1, C2, F, G) :- 
    call(C2, F, H), 
    call(C1, H, G). 

/* stop getter */ 
id(X,X). 

/* stop setter */ 
id(_,X,X). 

這裏有一些例子運行:

Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.14-1-ga20f192) 
Copyright (c) 1990-2015 University of Amsterdam, VU Amsterdam 

?- ['lens.pro']. 

?- call([email protected], id, F), call(F, bicycle(wheel(1330, 12), wheel(1440, 16)), X). 
F = front(spokes(id)), 
X = 16. 

?- call([email protected], id, F), call(F, bicycle(wheel(1330, 12), wheel(1440, 16)), X). 
F = back(circumference(id)), 
X = 1330. 

?- call([email protected], id, F), call(F, bicycle(wheel(1330, 12), wheel(1440, 16)), 1420, X). 
F = front(circumference(id)), 
X = bicycle(wheel(1330, 12), wheel(1420, 16)). 
+0

提示用別的替換id,你得到+ =等。 –