如何将这个Prolog程序转换成Lisp?

如何将这个Prolog程序转换成Lisp?,prolog,lisp,common-lisp,Prolog,Lisp,Common Lisp,我正在尝试学习CommonLisp,我想知道如何制作一个类似于AsMonomial的Prolog的解析器,但不知道从哪里开始 as_monomial(X, m(X, 0, [])) :- number(X), !. as_monomial(^(Y, Z), m(1, Z, [v(Z, Y)])) :- !. as_monomial(^(X, 0), m(1, 0, [])) :- !. as_monomial(*(X, ^(Y, Z)), m(G, K, Q)) :- as_

我正在尝试学习CommonLisp,我想知道如何制作一个类似于AsMonomial的Prolog的解析器,但不知道从哪里开始

as_monomial(X, m(X, 0, [])) :- number(X), !.  
as_monomial(^(Y, Z), m(1, Z, [v(Z, Y)])) :- !.  
as_monomial(^(X, 0), m(1, 0, [])) :-  !.  
as_monomial(*(X, ^(Y, Z)), m(G, K, Q)) :- 
  as_monomial(X, m(G, TD, Vars)), 
  K   is (TD + Z), 
  ordinamonomio([v(Z, Y)| Vars], Q),
  !.
as_monomial(*(X, Y), m(G, K, Q)) :- 
  as_monomial(X, m(G, TD, Vars)), 
  K is (TD + 1), 
  ordinamonomio([v(1, Y)| Vars], Q),
  !.
as_monomial(-(X), m(Q, Y, L)) :- 
  as_monomial(X, m(A, Y, L)), 
  Q is A *(-1), 
  !.
as_monomial(X, m(1, 1, [v(1, X)])).

在Prolog代码中,您主要依赖于模式匹配和递归,但不依赖于回溯,因此您可以轻松地将其转换为Common Lisp,而无需进行大量返工。我可以给你看一个骨架。如果你不熟悉Common Lisp,我强烈建议你阅读这本书

将函数声明为泛型函数,即根据一个或多个参数的类型或值动态分派的函数

(defgeneric as-monomial (term)
  (:documentation "Express a term as a monomial."))
根据泛型函数参数的类型或值专门化泛型函数。例如,您可以对数字进行特定的实现:

(defmethod as-monomial ((term number))
  `(m ,term 0 ()))
。。。另一个用于cons单元格,即复合术语:

(defmethod as-monomial ((term cons))
  (destructuring-bind (operator left &optional right) term
    (case operator
      (^ ...)
      (* ...)
      (- ...))
看。 您还可以具有默认行为:

;; fallback case
(defmethod as-monomial (term)
  `(m 1 1 ((v 1 ,term))))
当然,您可以定义一个只使用case或destructurebind的函数,但是泛型方法可以更好地扩展。对于复杂的模式匹配需求(此处并非如此),IMO,您可以使用模式匹配库,如。

参考:

我发现伊凡·布拉特科(Ivan Bratko)的书更适合学习DCG

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Lisprolog-简单Lisp的解释器。用序言写的。 马库斯·特里斯卡于2006年11月26日撰文triska@metalevel.at. 公共域代码。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ :-set_prolog_flag双引号,字符。 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 解析 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ParsinString,表达式:-短语表达式表达式表达式,字符串。 表达式[E|Es]> ws,expressionE,ws, !, % 单一解决方案:最长输入匹配 表情。 表达式[]->[]。 ws->[W],{char_typeW,space},ws。 ws->[]。 %数字N表示为nN,符号S表示为sS。 表达式a->symbolCs,{atom_charsA,Cs}。 表达式nn->numberCs,{number\u charsN,Cs}。 expressionList->,expressionList。 表达式[squote,Q]->',表达式Q。 数字[D | Ds]->数字,数字。 数字[D]->数字。 digitD->[D],{char_typeD,digit}。 符号[A|As]> [A] ,,
{memberchkA,+/-*>感兴趣的问题:我不能确定我的答案是否真的是你具体问题的答案。它更多的是对标题问题的答案,如何将这个Prolog程序转换成Lisp?而不是具体问题。我删除了,然后取消了删除。我知道答案在你所寻求的范围内,但更多的是一种理论类型如果你不认为它是一个答案,请让我知道,我会删除它。复制:@ RuneJoWig链接结果的目的地没有找到。它可以找到一个,但点击链接结果的错误。因为你是新的StAdvOver,请带上和阅读。虽然有趣,片段是ABO。ut将Lisp表达式解析为Prolog术语。我完全同意OP想做的事情。我完全同意@coredump。正是在阅读了你的答案,然后重新阅读了问题之后,我删除了我的答案。但是,在再次阅读并看到评论和答案的投票结果后,我决定让OP来决定。我我也同意关于这个问题不明确的投票结果。我总是觉得新人们如何能把扳手扔进这个问题很有趣。在这里很多年后,我只是尽我所能帮助新人们,因为我记得从论坛转到这种问答形式对我来说是多么令人沮丧。不需要感谢,但我很感激。这不是问题而是帮助其他人作为一个社区学习。我认为投票是一个标志,表明这是正确的方向。