表中的 Prolog 点

发布于 2024-12-25 12:59:22 字数 408 浏览 0 评论 0原文

我有一个给定的列表,表示二维列表 x。该表包含两个 1 的“点”,如下例所示:

xxxxxxxxxxxxxxxx
xx1111xxxx111xxx
xxx1111xxxx11xxx
x1111xxxxxx111xx

我只需将第二个点从 1 更改为 2,如下例所示:

xxxxxxxxxxxxxxxx
xx1111xxxx222xxx
xxx1111xxxx22xxx
x1111xxxxxx222xx

我需要一个名为 separate(L,M)< 的谓词/code> 将采用第一个列表 L 并生成第二个表 M

如果我们能够在不使用任何标准谓词(如“findall”等)的情况下解决这个问题,那就太好了......

I have a given list that represent a two dimensional list x. This table contains two "spots" of 1 as you can see in the example below:

xxxxxxxxxxxxxxxx
xx1111xxxx111xxx
xxx1111xxxx11xxx
x1111xxxxxx111xx

I need to change ONLY the second spot from 1 to 2 like the example below:

xxxxxxxxxxxxxxxx
xx1111xxxx222xxx
xxx1111xxxx22xxx
x1111xxxxxx222xx

I need a predicate called separate(L,M) that will take the first list L and will produce the second table M

It would be excellent if we can solve this without using any standard predicate like 'findall' etc ...

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

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

发布评论

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

评论(3

偏闹i 2025-01-01 12:59:22

您可以使用定语从句语法 (DCG) 来实现有限状态转换器。尽管 DCG 在生产方面没有提供太多组合操作,但它们在识别方面的实现相当出色。

所以你想要识别的是两种不同类型的 1 序列。所以基本上我猜输入行在扩展巴科斯范式(EBNF)中看起来如下:

line :== exs run1 exs run2 exs | exs.
exs  :== { "x" } "x".
run1 :== { "1" } "1".
run2 :== { "1" } "1".

对于识别问题,您可以编写一个没有属性的DCG(接下来是Prolog文本,您可以放入文件中或直接通过? - [用户]):

line --> exs, run1, exs, run2, exs | exs.

run1 --> "1", run1.
run1 --> "1".

run2 --> "1", run2.
run2 --> "1".

exs --> "x", exs.
exs --> "x".

以下是一些运行示例:

?- phrase(line,"xxx").
Yes 
?- phrase(line,"xxx111xxx111xxx").
Yes 
?- phrase(line,"xxx111xxx"). 
No

对于生产问题,您只需向 DCG 添加属性即可。使用
差异列表最简单:

line(I,O) --> exs(I,H), run1(H,J), exs(J,K), run2(K,L), exs(L,O) | exs(I,O).

run1([0'1|I],O) --> "1", run1(I,O).
run1([0'1|H],H) --> "1".

run2([0'2|I],O) --> "1", run2(I,O).
run2([0'2|H],H) --> "1".

exs([0'x|I],O) --> "x", exs(I,O).
exs([0'x|H],H) --> "x".

以下是一些运行示例:

?- phrase(line(R,[]),"xxx").
R = [120, 120, 120] 
?- phrase(line(R,[]),"xxx111xxx111xxx").
R = [120, 120, 120, 49, 49, 49, 120, 120, 120, 50, 50, 50, 120, 120, 120] 
?- phrase(line(R,[]),"xxx111xxx").
No

注意:0' 是字符代码的 Prolog 表示法。在 ascii 中,我们有 0'x = 120、0'1 = 49、0'2 = 50,这解释了结果。上面的代码应该可以在大多数 Prolog 系统上运行,因为它们支持 DCG。

再见

定语从句语法
http://en.wikipedia.org/wiki/Definite_clause_grammar

有限状态传感器
http://en.wikipedia.org/wiki/Finite_state_transducer

You could use Definite Clause Grammars (DCG) to implement a finite state transducer. Although DCGs don't deliver much compositional operations on the production side, they are quite good in implementing the recognition side.

So what you want to recognize is two different types of runs of 1's. So basically I guess an input line looks as follows in Extended Backus Naur Form (EBNF):

line :== exs run1 exs run2 exs | exs.
exs  :== { "x" } "x".
run1 :== { "1" } "1".
run2 :== { "1" } "1".

For the recognition problem you can write a DCG without attributes (what follows is a Prolog text, you can put in a file or directly consult it via ?- [user]):

line --> exs, run1, exs, run2, exs | exs.

run1 --> "1", run1.
run1 --> "1".

run2 --> "1", run2.
run2 --> "1".

exs --> "x", exs.
exs --> "x".

Here are some example runs:

?- phrase(line,"xxx").
Yes 
?- phrase(line,"xxx111xxx111xxx").
Yes 
?- phrase(line,"xxx111xxx"). 
No

For the production problem you just can add attributes to the DCG. Using
a difference list works easiest:

line(I,O) --> exs(I,H), run1(H,J), exs(J,K), run2(K,L), exs(L,O) | exs(I,O).

run1([0'1|I],O) --> "1", run1(I,O).
run1([0'1|H],H) --> "1".

run2([0'2|I],O) --> "1", run2(I,O).
run2([0'2|H],H) --> "1".

exs([0'x|I],O) --> "x", exs(I,O).
exs([0'x|H],H) --> "x".

Here are some example runs:

?- phrase(line(R,[]),"xxx").
R = [120, 120, 120] 
?- phrase(line(R,[]),"xxx111xxx111xxx").
R = [120, 120, 120, 49, 49, 49, 120, 120, 120, 50, 50, 50, 120, 120, 120] 
?- phrase(line(R,[]),"xxx111xxx").
No

Note: 0' is the Prolog notation for a character code. In ascii we have 0'x = 120, 0'1 = 49, 0'2 = 50, which explains the result. The above should run on most Prolog systems since they support DCGs.

Bye

Definite Clause Grammar
http://en.wikipedia.org/wiki/Definite_clause_grammar

Finite State Transducer
http://en.wikipedia.org/wiki/Finite_state_transducer

秋凉 2025-01-01 12:59:22

我们可以应用临时音译(仅适用于“水平”列表):

transliteration(Matrix, Translit) :-
  maplist(transliteration(not_seen), Matrix, Translit).

transliteration(_State, [], []).
transliteration(State, [X|Xs], [Y|Ys]) :-
  transliteration(State, X, NewState, Y),
  transliteration(NewState, Xs, Ys).

% handle only required state change
transliteration(not_seen, 0'1, seen_first, 0'1).
transliteration(seen_first, C, seen_last, C) :- C =\= 0'1.
transliteration(seen_last, 0'1, seen_last, 0'2).
% catch all, when no change required
transliteration(State, C, State, C).

We can apply ad hoc transliteration (just for 'horizontal' lists):

transliteration(Matrix, Translit) :-
  maplist(transliteration(not_seen), Matrix, Translit).

transliteration(_State, [], []).
transliteration(State, [X|Xs], [Y|Ys]) :-
  transliteration(State, X, NewState, Y),
  transliteration(NewState, Xs, Ys).

% handle only required state change
transliteration(not_seen, 0'1, seen_first, 0'1).
transliteration(seen_first, C, seen_last, C) :- C =\= 0'1.
transliteration(seen_last, 0'1, seen_last, 0'2).
% catch all, when no change required
transliteration(State, C, State, C).
浊酒尽余欢 2025-01-01 12:59:22

与@chac建议的解决方案类似,但更直接。

walk(L, R) :- walk(s0, L, R).
walk(_, [], []). % finish
walk(s0, [0'1|T], [0'1|R]) :- walk(s1, T, R).
walk(s1, [0'x|T], [0'x|R]) :- walk(s2, T, R).
walk(s2, [0'1|T], [0'2|R]) :- walk(s2, T, R).
walk(S, [H|T], [H|R]) :- walk(S, T, R). % keep state and do nothing

Similar to solution suggested by @chac, but more direct.

walk(L, R) :- walk(s0, L, R).
walk(_, [], []). % finish
walk(s0, [0'1|T], [0'1|R]) :- walk(s1, T, R).
walk(s1, [0'x|T], [0'x|R]) :- walk(s2, T, R).
walk(s2, [0'1|T], [0'2|R]) :- walk(s2, T, R).
walk(S, [H|T], [H|R]) :- walk(S, T, R). % keep state and do nothing
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文