对于length / 2,如何添加人类可读的变量名称

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对于length / 2,如何添加人类可读的变量名称相关的知识,希望对你有一定的参考价值。

如何为系统生成的变量名显示人类可读的变量名?

举个简单的例子:

?- length(Ls,N).
Ls = [],
N = 0 ;
Ls = [_5112],
N = 1 ;
Ls = [_5112, _5118],
N = 2 ;
Ls = [_5112, _5118, _5124],
N = 3

会更好

?- length(Ls,N).
Ls = [],
N = 0 ;
Ls = [a],
N = 1 ;
Ls = [a, b],
N = 2 ;
Ls = [a, b, c],
N = 3 

制图

_5112 = a
_5118 = b
_5124 = c

细节

我找到的最接近的解决方案使用read_term/2,如answer中使用variable_names(Vars)选项所示,但是我的问题不使用read_term从控制台获取该术语。

如果这是重复,请告诉我;我找不到一个。


真正的问题是基于生成测试用例数据:

?- length(Ls,N),list_partitionedNU(Ls,Ps).
Ls = Ps, Ps = [],
N = 0 ;
Ls = [_5242],
N = 1,
Ps = [[_5242]] ;
Ls = [_5242, _5248],
N = 2,
Ps = [[_5242], [_5248]] ;
Ls = [_5242, _5248],
N = 2,
Ps = [[_5242, _5248]] ;
Ls = [_5242, _5248, _5254],
...

有关this的信息,请参阅thislist_partitionedNU/2


跟进后的答案。

基于威廉的answer

partitions(Ps) :-
  length(Ls,N),
  assign(Ls),
  list_partitionedNU(Ls,Ps).

?- partitions(Ps).
Ps = [] ;
Ps = [[a]] ;
Ps = [[a], [b]] ;
Ps = [[a, b]] ;
Ps = [[a], [b], [c]] ;
Ps = [[a], [b, c]] ;
Ps = [[a, b], [c]] ;
Ps = [[a, c], [b]] ;
Ps = [[a, b, c]] ;
Ps = [[a], [b], [c], [d]] ;
Ps = [[a], [b], [c, d]] ;
Ps = [[a], [b, c], [d]] ;
Ps = [[a], [b, d], [c]] ;
Ps = [[a], [b, c, d]] ;
Ps = [[a, b], [c], [d]] ;
Ps = [[a, c], [b], [d]] ;
Ps = [[a, d], [b], [c]] ;
Ps = [[a, b], [c, d]] ;
Ps = [[a, c], [b, d]] ;
Ps = [[a, d], [b, c]] ;
Ps = [[a, b, c], [d]] ;
Ps = [[a, b, d], [c]] ;
Ps = [[a, c, d], [b]] ;
Ps = [[a, b, c, d]] ;
...

基于CapelliC的answer

partitions(Ps) :-
    length(Ls,N),
    numbervars(Ls,0,N),
    list_partitionedNU(Ls,Ps).

?- partitions(Ps).
Ps = [] ;
Ps = [[A]] ;
Ps = [[A], [B]] ;
Ps = [[A, B]] ;
Ps = [[A], [B], [C]] ;
Ps = [[A], [B, C]] ;
Ps = [[A, B], [C]] ;
Ps = [[A, C], [B]] ;
Ps = [[A, B, C]] ;
Ps = [[A], [B], [C], [D]] ;
Ps = [[A], [B], [C, D]] ;
Ps = [[A], [B, C], [D]] ;
Ps = [[A], [B, D], [C]] ;
Ps = [[A], [B, C, D]] ;
Ps = [[A, B], [C], [D]] ;
Ps = [[A, C], [B], [D]] ;
Ps = [[A, D], [B], [C]] ;
Ps = [[A, B], [C, D]] ;
Ps = [[A, C], [B, D]] ;
Ps = [[A, D], [B, C]] ;
Ps = [[A, B, C], [D]] ;
Ps = [[A, B, D], [C]] ;
Ps = [[A, C, D], [B]] ;
Ps = [[A, B, C, D]] ;
...
答案

我们可以构造一个谓词,它在递归时的仿函数中为变量“赋值”,并使用累加器跟踪分配的最新“名称”。

例如:

assign(Term) :-
    assign(Term, 97, _).

assign(X, N, N1) :-
    var(X),
    !,
    char_code(X, N),
    N1 is N+1.
assign(F, N, N1) :-
    F =.. [_|A],
    assign_list(A, N, N1).

assign_list([], N, N).
assign_list([H|T], N, NT) :-
    assign(H, N, N1),
    assign_list(T, N1, NT).

例如:

?- length(L, _), assign(L).
L = [] ;
L = [a] ;
L = [a, b] ;
L = [a, b, c] ;
L = [a, b, c, d] ;
L = [a, b, c, d, e] ;
L = [a, b, c, d, e, f] .
?- Q = [L, [_, _]], length(L, _), assign(Q).
Q = [[], [a, b]],
L = [] ;
Q = [[a], [b, c]],
L = [a] ;
Q = [[a, b], [c, d]],
L = [a, b] ;
Q = [[a, b, c], [d, e]],
L = [a, b, c] .

因此,我们“遍历”树并为变量赋值。通过上述实现,我们不考虑现有的常量。因此,我们可能会将已存在的值分配给变量。此外,我们只是继续增加字符代码,所以最终我们将达到符号,控制字符和字符。

然而,通过首先检查仿函数并获得要跳过的常量列表,可以“解决”上述缺点。此外,术语的生成器当然可以改进,例如通过在aa之后产生z

@DanielLyons指出term_variables/2谓词,它可以轻松地缓解assign/1谓词,如:

assign(Term) :-
    term_variables(Term, Vars),
    assign_list(Vars, 97).

assign_list([], _).
assign_list([H|T], N) :-
    char_code(H, N),
    N1 is N+1,
    assign_list(T, N1).

这当然仍然没有解决上述缺点,尽管如上所述,我们可以通过使用除char_code之外的其他东西来获得常量名称,并通过首先使用wak来查找使用中的常量来解决这些问题。

另一答案

让我们不要忘记明显的选择:一个不同的Prolog处理器。

使用SICStus Prolog 4.5.0(try full-featured SICStus Prolog 30 days for free):

| ?- Xs = [_C,f(_E)|_], length(Xs,N).
N = 2, Xs = [_C,f(_E)] ? ;
N = 3, Xs = [_C,f(_E),_A] ? ;
N = 4, Xs = [_C,f(_E),_A,_B] ? ;
N = 5, Xs = [_C,f(_E),_A,_B,_D] ? ;
N = 6, Xs = [_C,f(_E),_A,_B,_D,_F] ? ;
N = 7, Xs = [_C,f(_E),_A,_B,_D,_F,_G] ? ...
另一答案

老人,但goldie numbervars/3已被重新审视:

?- length(L,5),numbervars(L,0,N).
L = [A, B, C, D, E],
N = 5.

不确定它真的有用,但很高兴探索......

?- length(L,5),numbervars(L,0'a,N).
L = [T3, U3, V3, W3, X3],
N = 102.

以上是关于对于length / 2,如何添加人类可读的变量名称的主要内容,如果未能解决你的问题,请参考以下文章

如何以人类可读的格式输出(到日志)多级数组?

pyplot:如何以人类可读的方式显式地对轴进行编号

人类可读的 JSON:又名在 json 转储中添加空格和中断

R - 如何将纬度和经度坐标转换为地址/人类可读的位置?

如何将字符串时间戳更改为人类可读的日期格式? [复制]

在 .htaccess 中启用人类可读的 URL