2016-09-06 71 views
2

我正在编写一个模块,它使用term_expansion/2来处理序言源文件。在这样做的时候,我使用=..或使用functor/3将其项目名称解析为谓词。 例如:在序言中更改谓词/函子的名称

?- functor(pred(foo, bar), N, _). 
N = pred. 

?- pred(foo, bar) =.. L. 
L = [pred, foo, bar]. 

现在我想的pred名称更改为(例如)pred_expanded并恢复正常的术语,使pred(foo, bar)变得pred_expanded(foo, bar)

我试过append(pred, "_expanded", F)append(pred, '_expanded', F)没有成功。

+5

使用ISO谓词**'atom_concat/3' **连接原子。 – mat

+0

@mat你为什么不写一个答案?如果在“扩展”名称的相同模块中碰巧存在一个谓词,会发生什么? (我知道这是使用term_expansion/2生成代码的更普遍的问题)。是否这样扩展发生在一个单独的过程中,即扩展的代码不会自动进一步扩展,即使有为其定义的扩展? – 2016-09-07 09:30:11

+1

@Boris:我想吸引更多的海报来解决这个问题,我认为这是一个很好的入门点,如元编程,术语扩展等许多重要的主题。如果我只是回答“使用atom_concat/3”,这会得到立即被接受,那么整个问题很快就会被遗忘,其他重要的和相关的事情,如你所提到的,将不可能在这个机会下讨论。不过,我也想帮助用户解决他们更直接的问题,所以我认为一个简短的评论是最好的,以满足这两个要求。 – mat

回答

1
change_functor(Term,NewFunctor,NewTerm) :- 
    Term =.. [_|Args], 
    NewTerm =.. [NewFunctor|Args]. 

term_expansion(Term,ExpandedTerm) :- 
    functor(Term,pred,2), 
    change_functor(Term,pred_expanded,ExpandedTerm). 

例如:

?- term_expansion(pred(foo,bar),T). 
T = pred_expanded(foo, bar). 

演示如何使用 “大学” 预定义的谓语。然而,这是最好的解决办法:

term_expansion(pred(A,B),pred_expanded(A,B)). 

如果您需要翻译任何仿函数,使用atom_concat/3为前面所说:

term_expansion(Term,ExpandedTerm) :- 
    functor(Term,F,_), 
    atom_concat(F,'_expanded',NewF), 
    change_functor(Term,NewF,ExpandedTerm). 

例子:

?- term_expansion(kk(1,2,3),N). 
N = kk_expanded(1, 2, 3).