2015-11-03 52 views
2

这是我使用的代码:序言 - 与格式列表的打印列表/ 2

printElement(L/C) :- format('~t~a - ~a~t~20+|', [L, C]). 
printElement(L) :- format('~t~a~t~20+|~t', L). 

printList([]) :- format('~n', []). 

printList([H|T]) :- 
    printElement(H), 
    printList(T). 

printLists([], _). 
printLists([H|T], N) :- 
    M is N + 1, 
    format('~d- |', M), 
    printList(H), 
    printLists(T, M). 

作为BL列出的清单我称之为谓语printLists(BL, 0).

我的目标是展示BL作为一个9x9网格与细胞大小相同。 相反,我得到这个:

output1

我想所有列显示为图像中的第一列,我的意思是我希望所有其他细胞具有相同的宽度。

为什么我的代码不能用于第二列等等?

+0

这里的另一种变通方法来尝试,我打了,并在SWI Prolog的工作:'printElement(L): - 格式('〜0 +〜t〜a〜t〜20 + |',L)。和'printElement(L/C):格式('〜0 +〜t〜a〜〜〜〜t〜20 + ',[L,C])。'。让我知道如果解决它。 – lurker

回答

1

下面是使用谓词来构建格式字符串(实际上是一个原子)和基于输入行的更新数据列表的不同方法。这通过构建整行的单一格式字符串来避免每行多个格式的问题,因此可以为每行调用一个单独的格式字符串format/2

% makeFormat/4 
% makeFormat(-RowData, -FormatPrefix, +NewRowData, +Format) 
% 
makeFormat([], F0, [], F) :- 
    atom_concat(F0, '~n', F). 
makeFormat([E|Es], F0, L, F) :- 
    ( E = A/B 
    -> atom_concat(F0, '~t~a - ~a~t~20+|', F1), 
     L = [A,B|Ls] 
    ; atom_concat(F0, '~t~a~t~20+|', F1), 
     L = [E|Ls] 
    ), 
    makeFormat(Es, F1, Ls, F). 

printLists([], _). 
printLists([H|T], N) :- 
    M is N + 1, 
    makeFormat(H,'~d- |', H1, Format), % make format starting with '~d- |' 
    format(Format, [M|H1]),    % write out the list with prefix 
    printLists(T, M). 
+0

这工作。谢谢! 您对'makeformat/4'的参数有不一致性。 在'printLists/2'上,您正在错误地调用'makeformat/4'的参数2和3。在您的谓词声明中,参数顺序是_LIST,FORMAT 0,NEW LIST,OUT FORMAT_,并且在您使用_LIST,NEW LIST,FORMAT 0,OUT FORMAT_的printLists/2调用中再次感谢您的时间 –

+0

@PedroPereira感谢您的发现。在最后一刻,我交换了一些争论,首先得到所有的输入,输出最后,显然没有在实际的调用中修复它。我将它固定在答案中。 – lurker

1

此机制的问题是,在此情况下,出于某种原因,format/2列定位似乎无法按预期在多次调用format/2之间正常工作。但是,如果您使用[email protected]格式说明符,它将实际上工作[OK,它可以可能工作,因为我只能在具有相同format/2选项的SWI Prolog上尝试它]。

[email protected]格式选项告诉format将下一个参数作为Prolog谓词调用。

下面是一个例子。取而代之的是:

printElement(L/C) :- format('~t~a - ~a~t~20+|', [L, C]). 
printElement(L) :- format('~t~a~t~20+|~t', L). 

试试这个:

printElement(L) :- 
    ( L = A/B 
    -> format('[email protected]', print2(A, B)) 
    ; format('[email protected]', print1(L)) 
    ). 

print2(L, C) :- format('~t~a - ~a~t~20+|', [L, C]). 
print1(L) :- format('~t~a~t~20+|', L). % Not sure why you have the extra '~t' 
             % in your format; I removed it 

注意,我把if-else构建以避免第二printElement/1L/C形式匹配。

+0

谢谢你的时间回答我的多个问题。 额外的'〜t'只是用来测试它是否会改变结果。 虽然我理解你的回答,但我得到了同样的结果。如果我打电话:'printElement(foo),printElement(test),printElement(baa)。' 我得到: “(制表符空间)foo(制表符空间)| test | baa |” 再一次感谢你的时间 –

+0

@PedroPereira好的,这是不幸的。显然这两个序言之间的行为有所不同。同样不幸的是,在执行'〜N +'时'format'似乎没有相对于当前光标位置进行操作。如果我想到别的什么,我会让你知道的。这似乎是一个基本的功能,应该可以简单地工作。 – lurker

1

这是另一种在SWI Prolog中可用的方法。您需要在SICSTUS Prolog中尝试它,看看它是否也可以在那里使用。只要进行以下谓词更新你原来的解决方案:

printElement(L/C) :- format('~0+~t~a - ~a~t~20+|', [L, C]). % added '~0+' 
printElement(L) :- format('~0+~t~a~t~20+|', L).    % added '~0+' 

printList([]) :- format('~n'). % [] argument unnecessary in format, so removed 

printElement,我在每一个格式字符串(原子)的开头加了~0+格式的其余部分发生之前建立的相对列位置。如果这在SICSTUS下不起作用,您可以尝试~1+。但在SWI中,我使用~0+获得预期产出。我喜欢这个解决方案比粘贴一个任意长的格式字符串更好。

原始代码测试:

?- printList([a,b,c]). 
     a   |b|c| 
true. 

更新代码的测试:

?- printList([a,b,c]). 
     a   |   b   |   c   | 
true.