我正在使用Steven Tanimoto的人工智能元素使用Common Lisp ,我无法弄清楚他的match
程序。到目前为止,我们的想法是逐步改进自动列表match
,从不太好的
(defun match1 (p s) (equalp p s))
这是match3
:
(defun match3 (p s)
(cond
((null p) (null s)) ;null clause
((or (atom p) (atom s)) nil) ;atom clause
((equalp (first p) (first s)) ;equal CAR clause
(match3 (rest p) (rest s)))
((eql (first p) '?) ; joker clause
(match3 (rest p) (rest s)))
(t nil))) ;extremal clause
所谓的 joker 条款应该匹配,即
(match3 '(a b ? d) '(a b c d)) ; yields t
但是下一个版本应该“匹配”这个
(match4 '((? x) b c (? y)) '(a b c d))
我引用
这将允许,例如,(上)表格不仅返回 是的,但也返回
a
与x
和d
的关联y
与match
的关联。这样,如果匹配用作a 在生产规则中,条件的动作部分可以 操纵与模式中的变量元素匹配的值。
......然后继续谈论alist的事情。然后重写(defun4 match4 (p s)
(cond
((and (null p) (null s))
'((:yes . :yes)))
((or (atom p) (atom s)) nil)
((equalp (first p) (first s))
(match4 (rest p) (rest s)))
((and
(equalp (length (first p)) 2)
(eql (first (first p)) '?)
(let ((rest-match
(match4 (rest p) (rest s))))
(if rest-match
(acons (first (rest (first p)))
(first s)
rest-match)))))
(t nil)))
:
(? x)
...所以如果有人可以通过首先告诉我为什么我们要在上面的示例中将a
与$artist->removeArtistCategory($artistCategory->getId());
进行比较来帮助我,那会有所帮助。基本上,我不清楚这里的目标是什么。如果有人可以解释这背后的动机,我想我可以挑选代码。否则,我完全迷失了。
答案 0 :(得分:2)
match3
引入了两个列表之间的简单模式匹配,其中第一个列表中的符号?
可以匹配第二个列表中的任何单个符号。因此,函数返回T
或NIL
,表示匹配过程成功或失败。
然后通过使用看似匹配变量的内容在match4
中引入了一种新的匹配。 (? x)
只是引入匹配变量的一种方式,在其他语言中可以写为?x
或类似的东西。这个想法是这个变量“捕获”第二个列表上匹配的符号,所以,例如,你以后可以用类似的方式使用它:
(match '(a (? x) (? y) (? x) b) '(a c d c b)) ; yes, since ‘c’ matches ‘?x’
(match '(a (? x) (? y) (? x) b) '(a c d e b)) ; no, since ‘c’ and ‘e’ are different
要有效使用此功能,当找到匹配项时,函数match
必须提供的不仅仅是值T
,而是成对(match variable, symbol matched)
,并使用它构建找到的匹配关联列表。所以,match4
通过使用acons
在cond的最后一个分支中返回这样的列表(首先它得到rest-match
,而不是“aconses”,匹配变量给出的对并找到符号)。特殊对(:yes . :yes)
只是终止此匹配列表的一种方式。
我想在本书后面会提供另一个匹配函数版本,其中找到的匹配项将用于该过程的后续部分。
答案 1 :(得分:0)
我有tanimoto的书,但最早要到明天才能访问它,但引用中提到的例子其实很好:
这样,如果匹配用作生产规则中的条件,则规则的操作部分可以操作与模式中的变量元素匹配的值。
Production rule systems是这种匹配有用的好例子。它允许规则编写者专注于领域知识,并保持处理规则的算法分离。
函数式编程的一些方法也大量使用模式匹配。但是,编程语言支持各不相同。 Common Lisp的制作者很容易编写自己的。