Prolog 人工智能语言中文论坛---打造优质Prolog学习交流园地
Would you like to react to this message? Create an account in a few clicks or log in to continue.
Prolog 人工智能语言中文论坛---打造优质Prolog学习交流园地

一个供Prolog爱好者学习与交流的地方


您没有登录。 请登录注册

變數互不相同

3 posters

向下  留言 [第1页/共1页]

1變數互不相同 Empty 變數互不相同 周六 八月 31, 2013 3:03 am

frankchiboy



請問假如我有很多個變元,譬如六個。我想要說他們都互不相同,除了下一個個打的方式:
W1 \= W2,
W1 \= W3,
W1 \= W4,
W1 \= W5,
W1 \= W6,
W2 \= W3,
W2 \= W4,
W2 \= W5,
W2 \= W6,
W3 \= W4,
W3 \= W5,
W3 \= W6,
W4 \= W5,
W4 \= W6,
W5 \= W6.


之外,有什麼比較快的方式嗎?

2變數互不相同 Empty 回复: 變數互不相同 周六 八月 31, 2013 11:36 am

yauhsien



代码:
Ws = [W1,W2,W3,W4,W5,W6],
setof(W, member(W,Ws), Ws1),
length(Ws1, N), length(Ws, N).

http://yauhsien.wordpress.com

3變數互不相同 Empty 回复: 變數互不相同 周六 八月 31, 2013 1:05 pm

frankchiboy



不好意思,可以指點一下為什麼嗎?我以為這三行只有輸出一些list和數字而已,為什麼可以讓變元都互相不相等呢?

yauhsien 写道:
代码:
Ws = [W1,W2,W3,W4,W5,W6],
setof(W, member(W,Ws), Ws1),
length(Ws1, N), length(Ws, N).

4變數互不相同 Empty 回复: 變數互不相同 周六 八月 31, 2013 2:11 pm

yauhsien



第一行,将变元收集成一数组。

第二行,由数组取出值的集合。此时,假如变元彼此不同,则取得全部的值。
假如有些变元彼此相同,则在集合里合并为同一个值。

第三行,纯粹比较原数组与取出的集合长度是否相同。如果长度相同,代表变元彼此不同。

你的问题所写的十五行,也是只判断任何二个变元是不是相同,而没有直接生成变元。
同理,我写的三行也是只有判断。
只要给我六个变元,如果六个变元的值都互相不同,则永真。
但是,假如六个变元有任意二个相同,则不永真。

frankchiboy 写道:不好意思,可以指點一下為什麼嗎?我以為這三行只有輸出一些list和數字而已,為什麼可以讓變元都互相不相等呢?

yauhsien 写道:
代码:
Ws = [W1,W2,W3,W4,W5,W6],
setof(W, member(W,Ws), Ws1),
length(Ws1, N), length(Ws, N).

http://yauhsien.wordpress.com

5變數互不相同 Empty 回复: 變數互不相同 周六 八月 31, 2013 7:16 pm

frankchiboy



感謝兩位,這邊附上我要解的題目與答案。

Exercise 2.4 Here are six Italian words:

astante , astoria , baratto , cobalto , pistola , statale .

They are to be arranged, crossword puzzle fashion, in the following grid:

變數互不相同 Oker

The following knowledge base represents a lexicon containing these words:

word(astante, a,s,t,a,n,t,e).
word(astoria, a,s,t,o,r,i,a).
word(baratto, b,a,r,a,t,t,o).
word(cobalto, c,o,b,a,l,t,o).
word(pistola, p,i,s,t,o,l,a).
word(statale, s,t,a,t,a,l,e).

Write a predicate crossword/6 that tells us how to fill in the grid. The first three arguments should be the vertical words from left to right, and the last three arguments the horizontal words from top to bottom.

Ans:

word(astante, a,s,t,a,n,t,e).
word(astoria, a,s,t,o,r,i,a).
word(baratto, b,a,r,a,t,t,o).
word(cobalto, c,o,b,a,l,t,o).
word(pistola, p,i,s,t,o,l,a).
word(statale, s,t,a,t,a,l,e).

crossword(W1, W2, W3, W4, W5, W6):-
word(W1, A11, A12, A13, A14 ,A15, A16, A17),
word(W6, A61, A62, A63, A64 ,A65, A66, A67),
word(W2, A21, A22, A23, A24 ,A25, A26, A27),
word(W3, A31, A32, A33, A34 ,A35, A36, A37),
word(W4, A41, A42, A43, A44 ,A45, A46, A47),
word(W5, A51, A52, A53, A54 ,A55, A56, A57),
A12 = A42,
A14 = A52,
A16 = A62,
A22 = A44,
A24 = A54,
A26 = A64,
A32 = A46,
A34 = A56,
A36 = A66,

Ws = [W1,W2,W3,W4,W5,W6],
setof(W, member(W,Ws), Ws1),
length(Ws1, N), length(Ws, N).

6變數互不相同 Empty 回复: 變數互不相同 周日 九月 01, 2013 1:41 pm

frankchiboy



抱歉,小弟實在困惑。我查了這些predicates。我的理解是,不過就是把Ws在重新列一次到Ws1,尤其我測試:
?- Ws = [W1,W2,W3,W4,W5,W6],
| setof(W, member(W,Ws), Ws1).
Ws = Ws1, Ws1 = [W1, W2, W3, W4, W5, W6].
不是就只是把Ws列出來然後改名字為Ws1而已嗎(看不出有相同的變元,和把他們合併的動作)?為什麼這樣就可以限制兩兩不相同?我可能在setof的語意尚不太瞭解。

yauhsien 写道:第一行,将变元收集成一数组。

第二行,由数组取出值的集合。此时,假如变元彼此不同,则取得全部的值。
假如有些变元彼此相同,则在集合里合并为同一个值。

第三行,纯粹比较原数组与取出的集合长度是否相同。如果长度相同,代表变元彼此不同。

你的问题所写的十五行,也是只判断任何二个变元是不是相同,而没有直接生成变元。
同理,我写的三行也是只有判断。
只要给我六个变元,如果六个变元的值都互相不同,则永真。
但是,假如六个变元有任意二个相同,则不永真。

frankchiboy 写道:不好意思,可以指點一下為什麼嗎?我以為這三行只有輸出一些list和數字而已,為什麼可以讓變元都互相不相等呢?

yauhsien 写道:
代码:
Ws = [W1,W2,W3,W4,W5,W6],
setof(W, member(W,Ws), Ws1),
length(Ws1, N), length(Ws, N).

7變數互不相同 Empty 回复: 變數互不相同 周日 九月 01, 2013 3:29 pm

Mercury Liao


Admin

前面的写法确实没法做到你想要的。
因为在prolog 里,"A \= B"意思并不是A不等于B,而是A无法和B匹配,或者说A无法和B绑定。
所以只要A与B都是变量,那A \= B一定是false,因为A和B都是变量的情形下A与B自然可以匹配以致相等。

所以你查询?- A \= B,它直接告诉你false。
光是这么简单的两个变量都无法直接说他们不等,更不要说6个变量了。

因此,要达到你所谓的"两两变量不相等",
只能是让prolog先给这6个变量绑定具体的值后,再透过执行一些如"list_to_set(W, S), length(S, 6)"的句子,
来排除那些W中有重复值的选项,prolog会回溯直到找到6个值彼此不相等的解答。

frankchiboy 写道:抱歉,小弟實在困惑。我查了這些predicates。我的理解是,不過就是把Ws在重新列一次到Ws1,尤其我測試:
?- Ws = [W1,W2,W3,W4,W5,W6],
|    setof(W, member(W,Ws), Ws1).
Ws = Ws1, Ws1 = [W1, W2, W3, W4, W5, W6].
不是就只是把Ws列出來然後改名字為Ws1而已嗎(看不出有相同的變元,和把他們合併的動作)?為什麼這樣就可以限制兩兩不相同?我可能在setof的語意尚不太瞭解。

yauhsien 写道:第一行,将变元收集成一数组。

第二行,由数组取出值的集合。此时,假如变元彼此不同,则取得全部的值。
假如有些变元彼此相同,则在集合里合并为同一个值。

第三行,纯粹比较原数组与取出的集合长度是否相同。如果长度相同,代表变元彼此不同。

你的问题所写的十五行,也是只判断任何二个变元是不是相同,而没有直接生成变元。
同理,我写的三行也是只有判断。
只要给我六个变元,如果六个变元的值都互相不同,则永真。
但是,假如六个变元有任意二个相同,则不永真。

frankchiboy 写道:不好意思,可以指點一下為什麼嗎?我以為這三行只有輸出一些list和數字而已,為什麼可以讓變元都互相不相等呢?

yauhsien 写道:
代码:
Ws = [W1,W2,W3,W4,W5,W6],
setof(W, member(W,Ws), Ws1),
length(Ws1, N), length(Ws, N).

http://prolog.longluntan.net

8變數互不相同 Empty 回复: 變數互不相同 周日 九月 01, 2013 4:53 pm

yauhsien



你需要先理解何谓集合。相对的,要学会什麽不是集合。

当我收集一份数组 Ws = [W1,W2,W3,W4,W5,W6] 时,能说是个集合吗?得看情况。

然而,当由 setof(W, member(W,Ws), Ws1) 产生 Ws1 时,我可说, Ws1 必是集合。集合的定义就是所包含的项目彼此不相同。因此,假如能收集为集合 Ws1 的来源数组 Ws 长度相同,隐含 Ws 中不包含重复项目。

以下这一行,你说「只是把Ws重列一次到Ws1」,但真的是这样子吗?
代码:
setof(W, member(W,Ws), Ws1)
member/2 的意义确实是取出每一个项目,但是, setof/3 的意义是,将重复的项目删减,使结果成为内容项目彼此不相同的数组,也就是集合。
从Ws变成Ws1,并不是改名字,而是重列、并且删减重复!

也许你的不理解,是先以为 Ws 的内容彼此先不同了。但是 Ws 可能是什麽呢?
可能是 [a, a, a, a, a, a] 对吧?
可回头看 crossword/6 ,你自己并没有预先设定 W1 到 W6 这些变元彼此一定不同。
但是在你的想法中,似乎直接认为 W1 到 W6 一定不同。

我所写的三行,必须理解为数学证明、逻辑证明。
若理解为纯粹产生为列表,那是思考走错方向了,还要多加油。


frankchiboy 写道:抱歉,小弟實在困惑。我查了這些predicates。我的理解是,不過就是把Ws在重新列一次到Ws1,尤其我測試:
?- Ws = [W1,W2,W3,W4,W5,W6],
|    setof(W, member(W,Ws), Ws1).
Ws = Ws1, Ws1 = [W1, W2, W3, W4, W5, W6].
不是就只是把Ws列出來然後改名字為Ws1而已嗎(看不出有相同的變元,和把他們合併的動作)?為什麼這樣就可以限制兩兩不相同?我可能在setof的語意尚不太瞭解。

yauhsien 写道:第一行,将变元收集成一数组。

第二行,由数组取出值的集合。此时,假如变元彼此不同,则取得全部的值。
假如有些变元彼此相同,则在集合里合并为同一个值。

第三行,纯粹比较原数组与取出的集合长度是否相同。如果长度相同,代表变元彼此不同。

你的问题所写的十五行,也是只判断任何二个变元是不是相同,而没有直接生成变元。
同理,我写的三行也是只有判断。
只要给我六个变元,如果六个变元的值都互相不同,则永真。
但是,假如六个变元有任意二个相同,则不永真。

frankchiboy 写道:不好意思,可以指點一下為什麼嗎?我以為這三行只有輸出一些list和數字而已,為什麼可以讓變元都互相不相等呢?

yauhsien 写道:
代码:
Ws = [W1,W2,W3,W4,W5,W6],
setof(W, member(W,Ws), Ws1),
length(Ws1, N), length(Ws, N).

http://yauhsien.wordpress.com

9變數互不相同 Empty 回复: 變數互不相同 周一 九月 02, 2013 4:47 am

yauhsien



代码:
1 ?- Ws = [W1,W2], setof(W,member(W,Ws),Ws1), length(Ws1,N), length(Ws,N).
Ws = Ws1, Ws1 = [W1, W2],
N = 2.
以上因W1,W2都未赋予初值,所以是彼此不同的变量。结果可见,因为Ws=Ws1,所以保证Ws内的W1与W2不相同。

代码:
2 ?-  Ws = [W1,W2], W1=a, W2=a, setof(W,member(W,Ws),Ws1), Ws\=Ws1.
Ws = [a, a],
W1 = W2, W2 = a,
Ws1 = [a].
以上,则因为W1与W2与同一值unified,所以,可知道Ws与Ws1不可unify,因此,隐含了Ws内有至少二个项目相同。

http://yauhsien.wordpress.com

返回页首  留言 [第1页/共1页]

您在这个论坛的权限:
不能在这个论坛回复主题