我正在使用SWI Prolog学习Prolog的大学 大学考试,我对使用univ =的练习如何运作有所怀疑。 =..
谓词执行 furmulas 公式的符号操作,其中频繁操作替代 替换< / em>另一个表达式的子表达式。
执行定义以下关系:
替代品(SubTerm,Term,SubTerm1,Term1)
如果Term1 rappresent 表示其中所有出现的SubTerm都被SubTerm1替换的术语表达式,则为TRUE。
例如,如果我有:
替代物(sin(x),2 *(sin(x)),t,F)。
然后: F = 2 * t * f(t)因为所有sin(x)次出现都被t取代
这是解决方案(在布拉特科书上找到),但我对我的解释不太确定:
% substitute( Subterm, Term, Subterm1, Term1)
% Term1 is Term with all occurrences (by matching)
% of Subterm are replaced by Subterm1.
% Test: ?- substitute( b, f(a,b,c), e, F).
% Test: ?- substitute( b, f(a,X,c), e, F).
% Test: ?- substitute( b, f(a,X,Y), e, F).
% Test: ?- substitute( a+b, f( a, A+B), v, F).
% Test: ?- substitute(b,B,e,F).
% Test: ?- substitute(b,b,e,F).
% Test: ?- substitute(b,a,e,F).
% Logic, there are three cases:
% If Subterm = Term then Term1 = Subterm1
% otherwise if Term is 'atomic' (not a structure)
% then Term1 = Term (nothing to be substituted)
% otherwise the substitution is to be carried
% out on the arguments of Term.
/* Case 1: SubTerm = Term --> SubTerm1 = Term1 */
substitute(Term, Term, Term1, Term1) :- !.
% Case 2: Se Term è atomico non c'è niente da sostituire
substitute( _, Term, _, Term) :- atomic(Term), !.
/* Case 3:
substitute(Sub, Term, Sub1, Term1) :-
Term =.. [F|Args], % Term è composto da: F è il FUNTORE PRINCIPALE ed Args è la lista dei suoi argomenti
substlist(Sub, Args, Sub1, Args1), % Sostituisce Sub1 al posto di Sub nella lista degli argomenti Args generando Args1
Term1 =.. [F|Args1]. % Term1 è dato dal FUNTORE PRINCIPALE F e dalla nuova lista degli argomenti Args1
/* sublist: sostituisce all'interno della lista degli argomenti: */
substlist(_, [], _, []).
substlist(Sub, [Term|Terms], Sub1, [Term1|Terms1]) :-
/* L'elemento in testa Term1 corrisponde all'eventuale sostituzione */
substitute(Sub, Term, Sub1, Term1),
/* Il problema è già risolto per le sottoliste e Terms1 rappresenta la sottolista Terms in cui tutte le occorrenze di Sub
sono già state sostituite con Sub1:
*/
substlist(Sub, Terms, Sub1, Terms1).
第一条规则 rappresent 代表 SubTerm = Term 的特定情况,因此最终 Term1 = SubTerm1 (因为我替代 替换整个术语)
第二条规则 rappresent 代表 Term是一个原子的特定情况,因此,无论SubTerm和SubTerm1的值如何,我不进行任何替换
我认为到目前为止这很简单,而且我的推理是正确的...旁边的它开始了更困难的部分,我不太确定......
规则:
substitute(Sub, Term, Sub1, Term1) :-
Term =.. [F|Args],
substlist(Sub, Args, Sub1, Args1),
Term1 =.. [F|Args1].
rappresent 代表一个通用案例,其中 Term <表达 rappresented 代表 / strong>,它可能的子表达式 rappresented 由Sub表示,一个新的子表达式 Sub1 ,当您遇到 Sub 和表达 Term1 ,表示SubTerm1替换所有SubTerm的术语表达式。
所以我可以用 whay 的方式以声明方式阅读:
如果以下事实为真,那么Term1 rappresent 表示术语表达式是正确的,其中所有出现的SubTerm都被SubTerm1替换:
1)原始表达式 Term 可以在一个列表中进行分解,该列表的头部是主仿函数F (在表达式evalutation中执行的第一个运算符)以及之后一个子列表 Args ,它支持这个仿函数的参数(我认为,在某些情况下,Args也可以包含其他仿函数,在这个计算步骤中,它不会是主要的算子...所以在这种情况下还有一些子问题需要解决)
2)确实,sublist(Sub,Args,Sub1,Args1)意味着这是正确的,Args1 rappresent Args,其中所有参数都等于Sub子表达式被Sub1子表达式替换。
3)最后,新的 Term1 必须是主要的仿函数F和新的参数列表 = .. 谓词的结果> Args1 (我认为= ..用新参数列表重新组合主仿函数
要在参数列表中执行替换,请使用 substlist 关系,将其划分为:
基础案例:
substlist(_, [], _, []).
简单地说:如果参数列表中没有任何内容,则无需替换
一般情况:
substlist(Sub, [Term|Terms], Sub1, [Term1|Terms1]) :-
/* L'elemento in testa Term1 corrisponde all'eventuale sostituzione */
substitute(Sub, Term, Sub1, Term1),
/* Il problema è già risolto per le sottoliste e Terms1 rappresenta la sottolista Terms in cui tutte le occorrenze di Sub
sono già state sostituite con Sub1:
*/
substlist(Sub, Terms, Sub1, Terms1).
这对我来说是更难理解的部分,我通过以下方式看待它,声明性阅读:
如果确实存在以下情况,那么[Term1 | Terms1]会显示所有Sub子句被Sub1 替换的参数列表[Term | Terms],这是正确的。
1)替换(Sub,Term,Sub1,Term1):这意味着它是TRUE,Term1(新参数的头部列出它是Term(旧参数列表的头部),如果Term == Sub ---&gt; Term1 == Sub1
2)substlist(Sub,Terms,Sub1,Terms1)表示所有子问题都已解决,我认为这是一个重点,因为参数列表 Term 是当前的参数列表主仿函数F但其中可以包含其他子函子,并且每个子函数都需要解决这个子问题,因为在这一步中执行Sub - &gt; Sub1替换。
但我对这最后的事情不太确定......
有人可以帮助我深刻理解它TNX
安德烈
答案 0 :(得分:3)
首先我要说的是,如果你把问题简明扼要,那就太好了。 Stackoverflow的整个想法是,问题和答案后来对其他人有用,写出好的问题是其中很重要的一部分。
接下来:所有编程语言都有权声称程序的实际源代码是对程序所做的最清晰,完整和详尽的解释(对于人类)。 Prolog 肯定有权获得该声明。它需要一点时间的习惯,但很快一个写得很好的谓词确实会告诉我更多关于程序逻辑的信息,而不是通过一种本身含糊不清的自然语言(无论是英语,意大利语,甚至是德语。
现在问你的问题......
=../2
做什么?我们可能会看here,但是,换句话说,我们左侧有f(a,b, ..., x)
,右侧有[f, a, b, ..., x]
。
假设递归,列表,匹配和统一不需要在这里解释,你已经广泛研究的程序,用意大利语评论,并用英语彻底解释,做了一件简单的事情:所有出现的 Term 中的子项被 Term1 中的 Subterm1 替换。
这样做了:
f(Args)
形式)分解为一个列表(使用=..
),然后递归地应用该列表中较简单的术语({{1 }})。之后,再次使用Args
重新组合列表。因此,如果你有一个嵌套术语,你仍然可以得到:
=..
这里唯一可能遇到的轻微困难是?- substitute(x, f( g( h(x,y,z), h(k,l,m) ), g(x,z) ), q, T).
T = f(g(h(q, y, z), h(k, l, m)), g(q, z)) ;
false.
和substitute
是相互递归的。如果这给你带来了很大的困难,你可以尝试做的一件事就是从谓词定义中删除所有注释,一次将整个程序放在屏幕上(或打印出来),然后查看它并思考它直到它有意义。它有效!