Prolog:DCGS - 将数字转换为英语

发布于 2024-10-10 17:25:21 字数 2042 浏览 2 评论 0原文

我正在练习在 Prolog 中使用 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 ).

I'm practicing using DCGs in Prolog. I take an integer like 123, 'explode' it into a list i.e. [1,2,3] and then I want to use DCG rules to get the output one-two-three. So far I can convert a list of one integer e.g. [1] into one but I don't know what to do when it comes to a list. I want to use DCGs as much as possible really as this is what I am practicing. Here's my current code:

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].

A possible solution WITHOUT using DCGs is what I've written before but I'm wondering how to write it using DCGs.

% 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 ).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情场扛把子 2024-10-17 17:25:22
digits([]) --> [].
digits([D|Ds]) --> digit(D), digits(Ds).

例子:

?- explode(123,X), digits(Digits,X,[]).
X = [1, 2, 3],
Digits = [one, two, three]
digits([]) --> [].
digits([D|Ds]) --> digit(D), digits(Ds).

Example:

?- explode(123,X), digits(Digits,X,[]).
X = [1, 2, 3],
Digits = [one, two, three]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文