如何将这个Prolog程序转换成Lisp?
我正在尝试学习CommonLisp,我想知道如何制作一个类似于AsMonomial的Prolog的解析器,但不知道从哪里开始如何将这个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_
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来决定。我我也同意关于这个问题不明确的投票结果。我总是觉得新人们如何能把扳手扔进这个问题很有趣。在这里很多年后,我只是尽我所能帮助新人们,因为我记得从论坛转到这种问答形式对我来说是多么令人沮丧。不需要感谢,但我很感激。这不是问题而是帮助其他人作为一个社区学习。我认为投票是一个标志,表明这是正确的方向。