gpt4 book ai didi

prolog - 是否应编写文本处理DCG来处理代码或字符?或两者?

转载 作者:行者123 更新时间:2023-12-03 13:44:27 25 4
gpt4 key购买 nike

在Prolog中,传统上有两种表示字符序列的方式:

  • 作为字符列表,它们是长度为1的原子。
  • 作为代码列表,只是整数。整数应解释为代码点,但未指定要使用的约定。作为一个(非常合理的)示例,在SWI-Prolog中,代码点的空间为Unicode(因此,代码点整数的范围从0到0x10FFFF)。

  • DCG是一种编写从左到右的列表处理代码的符号方式,旨在对“爆炸文本列表”进行解析。根据偏好,要处理的列表可以是字符列表或代码列表。但是,记下常量时,字符/代码处理的符号不同。通常会以“字符样式”或“代码样式”编写DCG吗?或者在模块导出DCG非终端的情况下,甚至可以采用char/code样式以实现可移植性?
    有些研究
    以下符号可用于表示DCG中的常量
  • 'a':一个字符(通常:单引号表示一个原子,如果 token 以小写字母开头,则可以将它们忽略。)
  • 0'a:a的代码。
  • ['a','b']:字符列表。
  • [ 0'a, 0'b ]:代码列表,即ab的代码(因此可以避免输入实际的代码点值)。
  • "a"代码列表。传统上,将双引号字符串分解为代码列表,并且即使SWI-Prolog将“双引号字符串”映射到特殊字符串数据类型,该表示法在DCG上下文中也适用于SWI-Prolog。
  • `0123`。传统上,将反引号内的文本映射到一个原子(我认为,95 ISO标准只是避免了对反引号字符串的含义进行具体说明。“这将是ISO/IEC 13211的这一部分的有效扩展,将反引号字符串定义为表示字符串常量。”)。在SWI-Prolog中,除非引号 back_quotes 设置为要求其他行为,否则引号内的文本会分解为代码列表。

  • 例子
    字符样式
    尝试识别“字符样式”中的“任何数字”并使它的“字符表示形式”在 C中可用:
    zero(C) --> [C],{C = '0'}. 

    nonzero(C) --> [C],{member(C,['1','2','3','4','5','6','7','8','9'])}.

    any_digit(C) --> zero(C).
    any_digit(C) --> nonzero(C).
    代码风格
    尝试识别“代码样式”中的“任何数字”:
    zero(C) --> [C],{C = 0'0}.

    nonzero(C) --> [C],{member(C,[0'1,0'2,0'3,0'4,0'5,0'6,0'7,0'8,0'9])}.

    any_digit(C) --> zero(C).
    any_digit(C) --> nonzero(C).
    字符/代码透明样式
    通过复制涉及常量的规则,DCG可以写为“字符/代码透明样式”。在上面的示例中:
    zero(C) --> [C],{C = '0'}. 
    zero(C) --> [C],{C = 0'0}.

    nonzero(C) --> [C],{member(C,['1','2','3','4','5','6','7','8','9'])}.
    nonzero(C) --> [C],{member(C,[0'1,0'2,0'3,0'4,0'5,0'6,0'7,0'8,0'9])}.

    any_digit(C) --> zero(C).
    any_digit(C) --> nonzero(C).
    上面的代码还接受一系列交替的代码和字符(因为不能输入内容列表)。这可能不是问题)。生成时,将获得不需要的任意字符/代码混合,然后需要添加剪切。
    字符/代码透明样式,带有附加的 Mode指示符
    另一种方法是明确指示模式。看起来很干净:
    zero(C,chars) --> [C],{C = '0'}. 
    zero(C,codes) --> [C],{C = 0'0}.

    nonzero(C,chars) --> [C],{member(C,['1','2','3','4','5','6','7','8','9'])}.
    nonzero(C,codes) --> [C],{member(C,[0'1,0'2,0'3,0'4,0'5,0'6,0'7,0'8,0'9])}.

    any_digit(C,Mode) --> zero(C,Mode).
    any_digit(C,Mode) --> nonzero(C,Mode).
    使用方言功能的字符/代码透明样式
    另外,可以使用Prolog方言的功能来实现字符/代码透明性。在SWI-Prolog中,存在 code_type/2 ,它实际上适用于代码和字符(有一个对应的 char_type/2,但恕我直言,在任何情况下,仅 chary_type/2适用于字符和代码)以及“数字类”代码和字符会产生复合 digit(X):
    ?- code_type(0'9,digit(X)).
    X = 9.

    ?- code_type('9',digit(X)).
    X = 9.

    ?- findall(W,code_type('9',W),B).
    B = [alnum,csym,prolog_identifier_continue,ascii,
    digit,graph,to_lower(57),to_upper(57),
    digit(9),xdigit(9)].
    因此,可以编写此代码以获得清晰的字符/代码透明性:
    zero(C) --> [C],{code_type(C,digit(0)}. 

    nonzero(C) --> [C],{code_type(C,digit(X),X>0}.

    any_digit(C) --> zero(C).
    any_digit(C) --> nonzero(C).
    特别是在SWI-Prolog中
    默认情况下,SWI-Prolog首选 代码。尝试这个:
    旗帜
  • back_quotes
  • double_quotes

  • 影响“标准代码”中 "string"`string`的解释。默认情况下, "string"解释为原子“字符串”,而 `string`解释为“代码列表”。
    在DCG之外,以下内容在SWI-Prolog中保留,所有标志均为默认设置:
    ?- string("foo"),\+atom("foo"),\+is_list("foo").
    true.

    ?- L=`foo`.
    L = [102,111,111].
    但是,在DCG中,默认情况下 "string"`string`都被解释为“代码”。
    在不更改任何设置的情况下,请考虑以下DCG:
    representation(double_quotes)    --> "bar".            % SWI-Prolog decomposes this into CODES 
    representation(back_quotes) --> `bar`. % SWI-Prolog decomposes this into CODES
    representation(explicit_codes_1) --> [98,97,114]. % explicit CODES (as obtained via atom_codes(bar,Codes))
    representation(explicit_codes_2) --> [0'b,0'a,0'r]. % explicit CODES
    representation(explicit_chars) --> ['b','a','r']. % explicit CHARS
    上面哪个匹配代码?
    ?- 
    findall(X,
    (atom_codes(bar,Codes),
    phrase(representation(X),Codes,[])),
    Reps).

    Reps = [double_quotes,back_quotes,explicit_codes_1,explicit_codes_2].
    上面哪个与字符匹配?
    ?- findall(X,
    (atom_chars(bar,Chars),phrase(representation(X),Chars,[])),
    Reps).
    Reps = [explicit_chars].
    当使用 swipl --traditional启动swipl时,使用 Syntax error: Operator expected 拒绝用反引号引起来的表示形式,但是否则没有任何变化。

    最佳答案

    Prolog标准(6.3.7)说:

    A double quoted list is either an atom (6.3.1.3) or a list (6.3.5).


    因此,以下应该成功:
    Welcome to SWI-Prolog (threaded, 64 bits, version 7.6.4)
    SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
    Please run ?- license. for legal details.

    For online help and background, visit http://www.swi-prolog.org
    For built-in help, use ?- help(Topic). or ?- apropos(Word).

    ?- Foo = "foo", (atom(Foo) ; Foo = [F, O, O]).
    false.
    因此,默认情况下,SWI-Prolog不是Prolog。可以,但是如果您想了解SWI-Prolog的非Prolog行为,请调整问题的标签。
    从定义还可以得出,即使在遵循Prolog的情况下,默认情况下双引号列表也是完全没有用的:它们可能表示原子,因此,无论字符/代码有什么区别,您甚至都不知道双引号列表实际上是一个列表。如果“列表”实际上是原子,即使只关心“文本”的结构属性(例如,它是回文)的DCG也是没有用的。
    因此,要使用DCG 处理文本的Prolog程序必须在启动时强制强制 double_quotes标志为其所需的值。您可以在代码和字符之间进行选择。与char相比,代码没有优势,但是在可读性和可键入性方面确实存在劣势。因此:
    答案:使用字符。明确设置double_quotes标志。

    关于prolog - 是否应编写文本处理DCG来处理代码或字符?或两者?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66301190/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com