Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Prolog 在SWI中使用SICStus-like-atomic_-list_-concat/3拆分原子_Prolog_Sicstus Prolog - Fatal编程技术网

Prolog 在SWI中使用SICStus-like-atomic_-list_-concat/3拆分原子

Prolog 在SWI中使用SICStus-like-atomic_-list_-concat/3拆分原子,prolog,sicstus-prolog,Prolog,Sicstus Prolog,我有一个类似于'id1,id2,id3'的原子,我想把它拆分成一个列表 使用与SWI中谓词原子\u list\u concat/3相同的方法 预期结果 ?- atomic_list_concat(L, ',', 'id1,id2,id3'). L = [id1, id2,id3] ?- atomic_list_concat([id1,id2,id3], ',', A). A = 'id1,id2,id3' | ?- L='id1,id2,id3' , atomic_list_concat(

我有一个类似于
'id1,id2,id3'
的原子,我想把它拆分成一个列表 使用与SWI中谓词原子\u list\u concat/3相同的方法

预期结果

?- atomic_list_concat(L, ',', 'id1,id2,id3').
L = [id1, id2,id3]

?- atomic_list_concat([id1,id2,id3], ',', A).
A = 'id1,id2,id3'
| ?- L='id1,id2,id3'  , atomic_list_concat(L,',',Ls).
L = 'id1,id2,id3',
Ls = [id1,id2,id3] ? ;
no

不管怎样,使用DCG有可能做到这一点而不考虑效率,这似乎相当相似

atomic_list_concat_(L, Sep, Atom) :-
        ( atom(Sep), ground(L), is_list(L) )
    ->  list_atom(L, Sep, Atom)
    ;   ( atom(Sep), atom(Atom) )
    ->  atom_list(Atom, Sep, L)
    ;   instantiation_error(atomic_list_concat_(L, Sep, Atom))
    .

list_atom([Word], _Sep, Word).
list_atom([Word|L], Sep, Atom) :-
    list_atom(L, Sep, Right),
    atom_concat(Sep, Right, Right1),
    atom_concat(Word, Right1, Atom).

atom_list(Atom, Sep, [Word|L]) :-
    sub_atom(Atom, X,N,_, Sep),
    sub_atom(Atom, 0,X,_, Word),
    Z is X+N,
    sub_atom(Atom, Z,_,0, Rest),
    !, atom_list(Rest, Sep, L).
atom_list(Atom, _Sep, [Atom]).
理由

atomic_list_concat/3是SWI Prolog中内置的一个方便工具,我认为我的代码没有完全涵盖规范(主要是因为我缺少用于测试的SICStus Prolog)。一个值得注意的区别是合格类型的鉴定。我坚持使用atom而不是list元素的原子类型,因为atom_concat/3是一个内置的ISO,因此应该禁止SWI Prolog实现接受的一些模式

关于代码,当类型测试决定了转换的方向时,实现很简单:我在list_atom/3中选择了一个简单的递归连接,可以很容易地进行优化,例如添加一个累加器,从而使其尾部递归优化,而atom_list/3则从左到右扫描寻找分隔符,当它找到它时,将其存储在列表头中,并获得用于递归的正确部分

关于一个简单的DCG实现,我用这段代码测试了一个很好的抽象列表//3,由实现,从而得到了这段紧凑的代码:

list_atom(L, Sep, Atom) :-
    phrase(list(atom_codes, atom_codes(Sep), L), AtomCs),
    atom_codes(Atom, AtomCs).

atom_codes(A) --> {atom_codes(A, Cs)}, Cs.

atom_list(Atom, Sep, L) :-
    atom_codes(Atom, AtomCs),
    phrase(list(any, atom_codes(Sep), LCs), AtomCs),
    !, maplist(atom_codes, L, LCs).

any([]) --> [].
any([C|Cs]) --> [C], any(Cs).

不需要列表就可以简单地直接实现//3…

我知道这不是一个完美的答案,但我做了一些努力,因为我的目标是更好地学习

代码

% NOTE  'Separator' must be a single character
% atomic_list_concat(Atom,Separator,List) 
% test => L='id1,id2,id3'  , atomic_list_concat(L,',',Ls).


atomic_list_concat(Atom,Separator,Res)       :-   atom_chars(Atom,CAtom),
                                                  atomic_list_concat_(CAtom,Separator,List),
                                                  maplist(atom_chars,Res,List).

% test => L='id1,id2,id3',atom_chars(L,CL)  , atomic_list_concat_(CL,',',Ls).       

atomic_list_concat_([],_,[[]]) :- ! .

atomic_list_concat_([A|As],Sep,[[]|Args])        :-    A=Sep,
                                                       atomic_list_concat_(As,Sep,Args).

atomic_list_concat_([A|As],Sep,[[A|Arg]|Args])   :-    A\=Sep,
                                                       atomic_list_concat_(As,Sep,[Arg|Args]).
测试

?- atomic_list_concat(L, ',', 'id1,id2,id3').
L = [id1, id2,id3]

?- atomic_list_concat([id1,id2,id3], ',', A).
A = 'id1,id2,id3'
| ?- L='id1,id2,id3'  , atomic_list_concat(L,',',Ls).
L = 'id1,id2,id3',
Ls = [id1,id2,id3] ? ;
no

你能解释一下为什么使用
ground/1
实例化错误/3
我试图使我的代码实例化模式类似于我认为(通过测试)被原子列表接受的模式吗。地面/1执行深度测试,查看列表内部。实例化_error/1应以ISO兼容的方式报告问题……感谢您对这一问题的解释……3