給定 2 個正數和負數文字(表示子句)串列,我想獲得這 2 個子句的所有可能的解決方案。
resolution([pos(X)|T],[H2|T2],R):- select(neg(X), [H2|T2],L),union(T,L,R).
resolution([neg(X)|T],[H2|T2],R):- select(pos(X),[H2|T2],L),union(T,L,R).
resolution([H|T],[H2|T2],R):-resolution(T,[H2|T2],R).
這適用于第一個串列 ([H|T]) 的第一個文字,但之后由于我撰寫遞回的方式,每次遞回后我都會丟失串列的頭部,這樣我就不會得到我的整個聯合2 原始串列,但第二個串列與洗掉文字后第一個串列的子集的并集。
我無法弄清楚我如何(嘗試)對第一個串列的每個元素與第二個元素進行決議,同時保留第一個串列的所有元素。
我的想法是這樣的:
resolution([[_]|[pos(X)|T]],[H2|T2],R):- select(neg(X),[H2|T2],L),select(pos(X),[[_]|[pos(X)|T]],Q),union(Q,L,R).
resolution([[_]|[neg(X)|T]],[H2|T2],R):- select(pos(X),[H2|T2],L),select(neg(X),[[_]|[neg(X)|T]],Q),union(Q,L,R).
resolution([[_]|[neg(X)|T]],[H2|T2],R):-resolution([[[_]|[neg(X)]]|T],[H2|T2],R).
試圖改變我用于解析度的元素,同時保持我的串列原樣,但這目前根本不起作用。
上面的代碼輸出什么:
?-resolution([pos(1),neg(3),pos(4)],[neg(1),pos(3),neg(5)],R).
R = [neg(3), pos(4), pos(3), neg(5)]
R = [pos(4), neg(1), neg(5)]
(使用 pos(1),neg(1) 和 neg(3),pos(3) 決議)
我希望它輸出什么:
?-resolution([pos(1),neg(3),pos(4)],[neg(1),pos(3),neg(5)],R).
R = [neg(3), pos(4), pos(3), neg(5)]
R = [pos(1),pos(4), neg(1), neg(5)]
保留第一個串列的 pos(1)。
uj5u.com熱心網友回復:
也可以通過[_ | _]在“result”引數中使用串列建構式來將元素“移動”到“result”串列,即將原始程式的最后一個子句更改為:
resolution([pos(X)|T],[H2|T2],R):- select(neg(X), [H2|T2],L),union(T,L,R).
resolution([neg(X)|T],[H2|T2],R):- select(pos(X),[H2|T2],L),union(T,L,R).
resolution([H|T], [H2|T2], [H | R]) :-
resolution(T, [H2|T2], R).
然后你去:
?- resolution([pos(1),neg(3),pos(4)],[neg(1),pos(3),neg(5)],R).
R = [neg(3), pos(4), pos(3), neg(5)] ;
R = [pos(1), pos(4), neg(1), neg(5)] ;
false.
這并不完美,因為如果H已經存在R呢?它會在結果中重復。所以也許改成這樣:
resolution([pos(X)|T],[H2|T2],R):- select(neg(X), [H2|T2],L),union(T,L,R).
resolution([neg(X)|T],[H2|T2],R):- select(pos(X),[H2|T2],L),union(T,L,R).
resolution([H|T], [H2|T2], Resolvent) :-
resolution(T, [H2|T2], R),
union([H], R, Resolvent).
有點可惜的是,這失去了謂詞的尾遞回性。
不管它值多少錢,我都不明白你為什么要為遞回而煩惱。您要做的就是從串列中選擇一個元素并保留所有其他元素。你的這個實作,加上我第一個版本的小修復,基本上是select/3它自己的一個展開版本。為什么不吃飽select/3?像這樣:
resolution(ClauseA, ClauseB, Resolvent) :-
select(Literal, ClauseA, RestA),
literal_opposite(Literal, OppositeLiteral),
select(OppositeLiteral, ClauseB, RestB),
union(RestA, RestB, Resolvent).
literal_opposite(pos(X), neg(X)).
literal_opposite(neg(X), pos(X)).
這實際上非常接近教科書對解析度的定義。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/367468.html
