2

単語を受け取り、それをキーボード上で左または右にシフトするProlog述語を書きたい...

...しかし、これまでのところ、どこから始めればよいのかわかりません。


例。キーボードで「loogika」という単語を左にシフトしてみましょう。

キーボードレイアウトqwertyの場合、左シフトするとエッジにぶつかることに注意してくださいa。これにはさまざまな方法で対処できますが、それぞれの「ソリューション」には独自の長所短所があるようです。

どうしようか?左シフトでa はなく、そのままにします。IMO、その厄介なことを切り替えないことは、2D物理距離を維持する方法で他のエッジ/コーナーケースを処理するときに維持するのが難しい代数的特性を失う価値があります... YMMV!Caps LockaCaps-Lock

サンプルPrologクエリ:

?-tipi ([ 、、、、、、、、] lo_ogika
        [ k、、、、、、、] )。i_ i_ f_uja
本当。

qwertyキーボードで「loogika」/「kiifuja」と書くと、どのキーが押されますか?見て、見る!

左シフトの前後、アニメーション

4

1 に答える 1

1

元の質問の場合:

:-use_module(library(clpfd)).

table([[1,2,3,4,5,6,7,8,9,0],[q,w,e,r,t,y,u,i,o,p], [a,s,d,f,g,h,j,k,l,;],[z,x,c,v,b,n,m,',','.','/']]).

shift_left(Char,New_Char):-
  table(Table),
  member(R,Table),
  nth1(I,R,Char),
  shift_l(I,NI),
  nth1(NI,R,New_Char).

shift_right(Char,New_Char):-
  table(Table),
  member(R,Table),
  nth1(I,R,Char),
  shift_r(I,NI),
  nth1(NI,R,New_Char).

shift_seq(left,Seq,NewSeq):-
  maplist(shift_left,Seq,NewSeq).
shift_seq(right,Seq,NewSeq):-
  maplist(shift_right,Seq,NewSeq).

shift_l(1,1).
shift_l(X,Y):-
  X>1,
  X#=Y+1.

shift_r(10,10).
shift_r(X,Y):-
  X<10,
  X#=Y-1.

クエリ:

?- shift_seq(left,[l,o,o,g,i,k,a],N).
N = [k, i, i, f, u, j, a] .

質問の g はタイプミスだと思います;)

報奨金には、この表のマンハッタン距離を使用できます。そして、その距離と重みを組み合わせて、レーベンシュタイン距離を計算します。私は次の適応を思いつきました。それが「実際の距離関数」であるかどうかはわかりません。

:-use_module(library(clpfd)).
:-use_module(library(aggregate)).

table([['1','2','3','4','5','6','7','8','9','0'],[q,w,e,r,t,y,u,i,o,p], [a,s,d,f,g,h,j,k,l,;],[z,x,c,v,b,n,m,',','.','/']]).

vert_distance(A,B,Table,Distance):-
  length(Table,L),
  Distance in 0..L,
  member(Row1,Table),
  member(Row2,Table),
  member(A,Row1),
  member(B,Row2),
  nth0(N1,Table,Row1),
  nth0(N2,Table,Row2),
  Distance #= abs(N1-N2).

hoz_distance(A,B,Table,Distance):-
  member(Row1,Table),
  member(Row2,Table),
  length(Row1,L),
  Distance in 0..L,
  nth0(N1,Row1,A),
  nth0(N2,Row2,B),
  Distance #= abs(N1-N2).

manhatten(A,B,Table,D):-
  vert_distance(A,B,Table,V),
  hoz_distance(A,B,Table,H),
  D#=V+H.

manhatten_string([],[],_,0).
manhatten_string(String1,String2,Table,D):-
  length(String1,L),
  length(String2,L),
  manhatten_string_(String1,String2,Table,D1),
  D is D1/L.
manhatten_string(S1,S2,Table,D):-
  length(S1,L1),
  length(S2,L2),
  D#=abs(L1-L2).

manhatten_string_([],[],_,0).
manhatten_string_(String1,String2,Table,D1):-
  String1 =[H1|T1],
  String2 =[H2|T2],
  manhatten(H1,H2,Table,DL),
  manhatten_string(T1,T2,Table,D0),
  D1 is D0+(DL/14).

lev(String1,String2,D):-
  length(String1,L1),
  length(String2,L2),
  0 is min(L1,L2),
  D is max(L1,L2).
lev(String1,String2,D):-
  String1 =[H1|T1],
  String2 =[H2|T2],
  lev(T1,String2,D1),
  lev(String1,T2,D2),
  lev(T1,T2,D3),
  D1plus1 is D1+1,
  D2plus1 is D2+1,
  indicator([H1],[H2],DM),
  D3plus is D3+DM,
  aggregate_all(min(X),member(X,[D1plus1,D2plus1,D3plus]),D).

indicator(Ai,Bj,0):-
  Ai=Bj.
indicator(Ai,Bj,D):-
  Ai\=Bj,
  table(Table),
  manhatten_string(Ai,Bj,Table,D).

クエリ:

?- lev([a,a],[b,a],D).
D = 0.35714285714285715 .

?- lev([a,a],[a,b],D).
D = 0.35714285714285715 .

?- lev([a,a],[a,b,c,d],D).
D = 2.142857142857143 .

?- lev([a],[],D).
D = 1 .

?- lev([a],[s],D).
D = 0.07142857142857142 .

?- lev([a],[o],D).
D = 0.6428571428571429 .

?- lev([a,b],[a,b],D).
D = 0 .

?- lev([a,b,c],[a,b],D).
D = 1 .

?- lev([a,b,c],[a,b,p],D).
D = 0.6428571428571429 .

ライブラリ(isub)もあります http://www.swi-prolog.org/pldoc/doc_for?object=section(0,%270%27,swi(%27/doc/packages/nlp.html%27)) . これの一部に適しているように見えます。

于 2015-10-01T22:07:32.317 に答える