1

suppose that I a have an atom which contains some keyN-separators , how I can generate a list that contains list of separate elements

1000<=N<=5000~ keys/elements

Example :

  ?- Atom ='elem1key1elem2key2elem3key1...elemN,keyN',
     split_atom_list(Atom,[key1,key2,keyN],Res_List).

Res_List = [elem1,key1,elem2,key2,...elemN,keyN];
yes
Ans Piter
  • 573
  • 1
  • 5
  • 17
  • So it takes a list of keys, throws out any key/element pairs not in the original atom, gives all the element/key pairs as separate list element, except the last one. The last one it throws out just the key and keeps the last element? You are also showing `elemN' in quotes, which is the same as without the quotes. Is there significance in that? With or without, in this case, they're the same thing. Perhaps another example would help, just to make sure the pattern is clear. – lurker Mar 06 '16 at 11:18
  • Shouldn't the result list of your example be, `Res_List = [elem1,key1,elem2,key2,...elemN,keyN];`? Or are you intentionally dropping the key for the last element? – lurker Mar 06 '16 at 11:34
  • @lurker the last element may be a key – Ans Piter Mar 06 '16 at 11:35
  • @lurker up to now I change the predicate atomic_concat_list [@CapelliC](http://stackoverflow.com/questions/35317539/split-atom-using-sicstus-like-atomic-list-concat-3-in-swi) to maintain a single key then finished with other keys recursively, but this is not the case – Ans Piter Mar 06 '16 at 11:45

1 Answers1

1

building on the answer referred in comments, using built-in predicates that (I think) are available in SICStus:

split_atom_list(Atom, Keys, [Res, Key|Res_List]) :-
    aggregate(min(P,(Q,K)), S^(
        member(K, Keys),
        sub_atom(Atom, P,Q,S, K)), min(X,(N,Key))),
    sub_atom(Atom, 0,X,_, Res),
    Z is X+N,
    sub_atom(Atom, Z,_,0, Rest),
    !, split_atom_list(Rest, Keys, Res_List).
split_atom_list(_Atom, _Keys, []).

The aggregation looks for the first (leftmost) matching key. You could change the base case to accept any unparsed tail:

split_atom_list(Atom, _Keys, [Atom]).
Community
  • 1
  • 1
CapelliC
  • 59,646
  • 5
  • 47
  • 90
  • thanks a lot, but I have a problem when I try this query ; `split_atom_list('id0 REF id1 FER id2 REF** id3 FER id4**',[' REF '],Res). Res = [id0,' REF ','id1 FER id2',' REF '] ?` – Ans Piter Mar 06 '16 at 12:45
  • I got other error with this query, `?-split_atom_list('id0<<:id1 – Ans Piter Mar 06 '16 at 15:32
  • What are the errors ? Maybe the 'grammar' is ambiguous ? Maybe there should be also '<' among separators... – CapelliC Mar 06 '16 at 15:50
  • I reverse the order of separators and I get this result ; `| ?- split_atom_list('id0<<:id1 – Ans Piter Mar 06 '16 at 16:20
  • plz can you explain why and how the predicate aggregate works also the^ and min(C,(A,B)) – Ans Piter Mar 06 '16 at 21:06
  • 1
    aggregate (see [here](http://www.swi-prolog.org/pldoc/doc_for?object=aggregate/3) an example) finds the min key position (P), saving as key length (Q) as well as the key (K) itself. ^ is required to let free the distance from end (S) – CapelliC Mar 06 '16 at 22:16
  • when i try to skipping space inside syntaxe with this [methode](http://stackoverflow.com/questions/14366036/removing-whitespace-from-strings-in-prolog) I got an error ? can you adding a sample example to inserting `s/0` inside syntaxe – Ans Piter Mar 08 '16 at 10:00
  • well, we are not using a DCG here, so I don't know where I could put the example. Which error ? stack overflow ? beware that two s//0 must **not** be consecutive (for instance joined by non terminals expanding to possible empty string) – CapelliC Mar 08 '16 at 10:30
  • I use this predicate `s --> "" ; " ", s.`, ident(X),`s`,ident(Y). – Ans Piter Mar 08 '16 at 10:51
  • The problem then is ambiguity ? To require at least 1 space you can change to: `s --> " "; " ", s.`, but I would introduce another predicate... – CapelliC Mar 08 '16 at 11:14
  • the predicat is in the link above(methode) ? – Ans Piter Mar 08 '16 at 14:00
  • like `s1 --> " ";" ",s.` and `s-->"";" ",s.` – Ans Piter Mar 08 '16 at 14:26
  • or, better, `s1 --> " ", s.` – CapelliC Mar 08 '16 at 15:20