2014-12-07 70 views
2

我在SICStus Prolog的一個程序,運行以下限制:Prolog的動態約束

processList([Elem1,Elem2|_], X) :- 
    (Elem1 #= 0 #/\ Elem2 #= X) #\/ 
    Elem1 #= X. 

但我需要把它設置動態

processList([Elem1,Elem2,Elem3|_], X) :- 
    (Elem1 #= 0 #/\ Elem2 #= 0 #/\ Elem3 #= X) #\/ 
    (Elem1 #= 0 #/\ Elem2 #= X)    #\/ 
    Elem1 #= X. 

如果我有4個元素叫它我會有更大的限制,但模式總是一樣的。

我已經查看了表謂詞(tuples_in/2,在SWI-Prolog中),但是這就需要我必須計算所有可能的有效值組合。

有沒有其他辦法可以做到這一點?

回答

2

使用 built-in謂語append/3 Prolog library謂語maplist/2我們寫:

 
:- use_module (library(lists)), [ maplist /2]). 

processList(Zs, X) :- 
    append (Prefix, [X|_], Zs), % `Zs` comprises `Prefix`, followed by `X` 
    maplist (= (0), Prefix).  % all items in `Prefix` are equal to 0 

看到它與SICStus Prolog的4.3.2行動!

| ?- processList(Zs, X). 
Zs = [X|_A] ? ; 
Zs = [0,X|_A] ? ; 
Zs = [0,0,X|_A] ? ; 
Zs = [0,0,0,X|_A] ? ; 
Zs = [0,0,0,0,X|_A] ? ; 
... 
+1

我覺得我還不夠清楚。我正在使用約束邏輯編程(使用clpr庫是精確的),所以我不能確定該元素是否爲0(如maplist那樣),我需要使用'#'運算符進行限制。當時我告訴我的教授說,我無法制定動態限制,甚至連他都無法解決問題(他們每年都會在課程中添加新問題以避免作弊)。我最終只需要使用第一段代碼。 – CMJunior 2015-09-18 13:14:55

+0

@CMJunior。請告訴我更多!我有一段時間沒有使用clp(R),但直覺上我會猜測它(原則上)可以與普通的Prolog使用語法統一進行互操作。 – repeat 2015-09-18 13:25:16

+1

我們需要製作一個簡易的序言版本作爲ABC拼圖。其中一個限制是,如果在列或行之前有一個字母,從列/行的角度來看董事會,則需要看到該字母,換句話說,所有的電路板空間,直到看到該字母爲止從這個角度來看必須是白色的(在我們的代碼中,值爲0)。 對於實驗室任務,我們還需要使電路板尺寸變爲動態,因此用戶會告訴程序他想要播放哪種電路板尺寸。這就產生了這個線程的限制問題。 – CMJunior 2015-09-19 14:46:58