Я практикую использование DCG в Прологе.Я беру целое число, например 123, «разрываю» его в список, т. Е. [1,2,3], а затем хочу использовать правила DCG, чтобы получить результат один-два-три.Пока что я могу преобразовать список из одного целого числа, например [1], в одно, но я не знаю, что делать, когда дело доходит до списка.Я хочу максимально использовать DCG, так как это то, что я практикую.Вот мой текущий код:
tests( 1, [1] ).
tests( 2, [67] ).
tests( 3, [183] ).
tests( 4, [999] ).
numToEng( N, Res ) :-
tests( N, W ),
print( 'test: ' ),print( W ),nl,
explode( W, Exploded ),
print( 'exploded: ' ),print( Exploded ),nl,
phrase( num(Res), Exploded ).
explode( N, Explosion ) :-
explode( N, [], Explosion ).
explode( 0, Explosion, Explosion ) :- !.
explode( N, Inter, Explosion ) :-
Test is N mod 10,
NewN0 is N - Test,
NewN1 is NewN0//10,
explode( NewN1, [Test|Inter], Explosion ).
num( X ) --> digit( X ).
digit(zero) --> [0].
digit(one) --> [1].
digit(two) --> [2].
digit(three) --> [3].
digit(four) --> [4].
digit(five) --> [5].
digit(six) --> [6].
digit(seven) --> [7].
digit(eight) --> [8].
digit(nine) --> [9].
Возможное решение БЕЗ использования DCG - это то, что я написал ранее, но мне интересно, как написать его с использованием DCG.
% test cases, called by numToEng/2
tests( 1, [1] ).
tests( 2, [67] ).
tests( 3, [183] ).
tests( 4, [999] ).
% dictionary
digit(0,zero).
digit(1,one).
digit(2,two).
digit(3,three).
digit(4,four).
digit(5,five).
digit(6,six).
digit(7,seven).
digit(8,eight).
digit(9,nine).
% take an integer e.g. 123 and explode it
% into a list i.e. [1,2,3]
explode( N, Explosion ) :-
explode( N, [], Explosion ).
explode( 0, Explosion, Explosion ) :- !.
explode( N, Inter, Explosion ) :-
Test is N mod 10,
NewN0 is N - Test,
NewN1 is NewN0//10,
explode( NewN1, [Test|Inter], Explosion ).
% take a number in digits and convert it
% into english e.g. [1,2,3] would be
% [one,two,three]
numToEng( N, Res ) :-
tests( N, Test ),
explode( Test, Exploded ),
numToEng( N, Exploded, [], Res ).
numToEng( _, [], Rev, Res ) :-
reverse( Rev, Res ).
numToEng( N, [H|T], Inter, Res ) :-
digit( H, Word ),
numToEng( N, T, [Word|Inter], Res ).