Foreach 不能在 Prolog 中工作
Foreach not working in Prolog
我正在尝试以下代码,其中 foreach 和 string_codes 分开工作:
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.
此代码仅打印第一个字母:
77 ?- foreach(member(X, [[97], [98],[99]]), (string_codes(S,X), writeln(S))).
a
问题出在哪里,如何解决?
编辑:地图列表只能以一种方式工作:
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)
实际上,每个数字应该是一个列表:
75 ?- maplist(string_codes, L, [[97], [98],[99]]).
L = ["a", "b", "c"].
如何将数字列表转换为列表列表?
我正在尝试:
tolistlist([H|T],[[H]|Outl]):-
writeln([[H]]),
tolistlist(T,Outl).
tolistlist([],[]).
它确实生成了该模式中的数字列表,但仍然不起作用:
[[115],[116]]
ERROR: string_codes/2: Type error: `character_code' expected, found `[116]' (a list)
105 ?-
foreach/2
实际上确实按照 documentation:
中描述的那样工作
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
。你可以写成:
forall(member(S, ["abc", "test"]), (string_codes(S, X), writeln(X))).
但是 X
的显示只是一个副作用,并没有被捕获。
正如@mat 建议的那样,这给您留下了 maplist/3
:
?- 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"
。
我正在尝试以下代码,其中 foreach 和 string_codes 分开工作:
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.
此代码仅打印第一个字母:
77 ?- foreach(member(X, [[97], [98],[99]]), (string_codes(S,X), writeln(S))).
a
问题出在哪里,如何解决?
编辑:地图列表只能以一种方式工作:
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)
实际上,每个数字应该是一个列表:
75 ?- maplist(string_codes, L, [[97], [98],[99]]).
L = ["a", "b", "c"].
如何将数字列表转换为列表列表?
我正在尝试:
tolistlist([H|T],[[H]|Outl]):-
writeln([[H]]),
tolistlist(T,Outl).
tolistlist([],[]).
它确实生成了该模式中的数字列表,但仍然不起作用:
[[115],[116]]
ERROR: string_codes/2: Type error: `character_code' expected, found `[116]' (a list)
105 ?-
foreach/2
实际上确实按照 documentation:
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
。你可以写成:
forall(member(S, ["abc", "test"]), (string_codes(S, X), writeln(X))).
但是 X
的显示只是一个副作用,并没有被捕获。
正如@mat 建议的那样,这给您留下了 maplist/3
:
?- 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"
。