Encore une autre façon .. tirer parti du fait que les numéros ascii pour 0..9 sont connus/fixes, alors aucune conversion de type ou des vérifications sont nécessaires, juste des soustractions.
% case 1: char is in decimal range 0-9, ie ascii 48,49,50,51,52,53,54,55,56,57
% so eg. char 48 returns integer 0
onechar(Char, Out) :-
between(48, 57, Char),
Out is Char -48.
% case 2: case 1 failed, dot '.' is ascii 46, use anonymous variable
onechar(46, _).
% execution
go(InString, OutList) :-
maplist(onechar, InString, OutList).
Exécution:
?- go("1..2...3..4", X).
X = [1, _G5638, _G5641, 2, _G5650, _G5653, _G5656, 3, _G5665, _G5668, 4]
Edit: a oublié de dire que cela fonctionne parce que les chaînes sont représentées sous forme d'une liste de numéros de ascii, si la chaîne "" est représentée en interne comme [48,49,50 51,52,53,54,55,56,57].
Onechar fait le calcul pour 1 de ces éléments de la liste, puis maplist appelle le même prédicat sur tous les éléments de la liste.
Edit 2: la 2ème règle était à l'origine:
% case 2: case 1 failed, output is an anon variable
onechar(_, _).
C'est trop généreux - probablement si l'entrée ne contient pas 0,9 ou un point, le prédicat devrait échouer.
Ces chiffres uniques sont-ils entre les points ou les entiers? En d'autres termes, est-ce que "12.23' va à '[1, 2, _, 2, 3]' ou '[12, _, 23]'? –
Ils sont à un seul chiffre. Donc 12.23 devient [1, 2, _, 2, 3] –