Foreach 在 Prolog 中不起作用 [英] Foreach not working in Prolog

查看:37
本文介绍了Foreach 在 Prolog 中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试以下代码,其中 foreach 和 string_codes 分别工作:

I am trying following code, where foreach and string_codes are working separately:

7 ?- string_codes("acid", D).
D = [97, 99, 105, 100].

8 ?- string_codes(S,  [116, 101, 115, 116]).
S = "test".


15 ?- foreach(member(S, ["test", "acid"]), writeln(S) ).
test
acid
true.

但不在一起:

14 ?- foreach(member(S, ["test", "acid"]), string_codes(S, X) ).
false.

17 ?- foreach(member(X,[[116, 101, 115, 116], [97, 99, 105, 100]]), string_codes(S, X)).
false.

此代码仅打印第一个字母:

Only first letter is printed with this code:

77 ?- foreach(member(X, [[97], [98],[99]]), (string_codes(S,X), writeln(S))).
a

问题出在哪里,如何解决?

Where is the problem and how can it be solved?

地图列表只有一种方式:

maplist works only one way:

74 ?- maplist(string_codes, ["test","acid"], L).
L = [[116, 101, 115, 116], [97, 99, 105, 100]].

73 ?- maplist(string_codes, L, [97, 98,99]).
ERROR: string_codes/2: Type error: `list' expected, found `97' (an integer)

实际上,每个数字都应该是一个列表:

Actually, each number should be a list:

75 ?- maplist(string_codes, L, [[97], [98],[99]]).
L = ["a", "b", "c"].

如何将数字列表转换为列表列表?

How can I convert a list of numbers into a list of lists?

我正在尝试:

tolistlist([H|T],[[H]|Outl]):-
    writeln([[H]]),
    tolistlist(T,Outl).
tolistlist([],[]).

它确实以该模式生成数字列表,但仍然不起作用:

It does produce list of numbers in that pattern but still does not work:

[[115],[116]]
ERROR: string_codes/2: Type error: `character_code' expected, found `[116]' (a list)
105 ?- 

推荐答案

foreach/2 实际上按照 文档:

如果结果的结合为真,则为真.不像 forall/2,它运行一个故障驱动循环,证明生成器的每个解决方案的目标,foreach/2 创建一个连接.连接的每个成员都是一个Goal 的副本,其中填充了与 Generator 共享的变量使用相应解决方案中的值.

True if conjunction of results is true. Unlike forall/2, which runs a failure-driven loop that proves Goal for each solution of Generator, foreach/2 creates a conjunction. Each member of the conjunction is a copy of Goal, where the variables it shares with Generator are filled with the values from the corresponding solution.

这意味着

foreach(member(S, ["abc", "test"]), string_codes(S, X))

相当于连词:

string_codes("abc", X), string_codes("test", X)

显然,这是错误的,因为 X 不能同时是 "abc""test" 的字符串代码列表.你可以在这里使用 forall/2 .forall(member(S, ["abc", "test"]), string_codes(S, X)) 成功,但不会显示X.你可以写成:

Clearly, this is false since X cannot both be the string code list for "abc" and "test". You could use forall/2 here. forall(member(S, ["abc", "test"]), string_codes(S, X)) succeeds, but won't display X. You could write it as:

forall(member(S, ["abc", "test"]), (string_codes(S, X), writeln(X))).

但是X的显示只是一个副作用,并没有被捕获.

But then the display of X is just a side-effect and not captured.

正如@mat 建议的那样,这给您留下了 maplist/3:

This leaves you with maplist/3 as @mat suggested:

?- maplist(string_codes, ["abc", "def"], ListOfCodeLists)
ListOfCodeLists = [[97, 98, 99], [100, 101, 102]].

反之亦然:

?- maplist(string_codes, ListOfStrings, [[97, 98, 99], [100, 101, 102]]).
ListOfStrings = ["abc", "def"].

此处,string_codes 将每个代码列表作为其第二个参数进行操作:string_codes(X, [97, 98, 99]) 生成 "abc"string_codes(X, [100, 101, 102]) 产生 "def".

Here, string_codes is operating on each list of codes as its second argument: string_codes(X, [97, 98, 99]) produces "abc" and string_codes(X, [100, 101, 102]) produces "def".

这篇关于Foreach 在 Prolog 中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆