Prolog:在键盘上左右移动文本

时间:2013-03-09 17:04:06

标签: autocomplete keyboard prolog levenshtein-distance

我想写一个Prolog谓词,它在键盘上左右移动移位 ...

...,但是 - 到目前为止 - 我没有线索从哪里开始。


示例。让我们在键盘上将“loogika”改为左侧!

请注意,如果我们的keyboard layoutqwerty, 我们在左移 a 时遇到边缘。我们可以处理它 不同的方式,但似乎每个“解决方案”都有自己的up- 下方。

那我们该怎么办?让左移 a Caps Lock ,而是保持 a 。 IMO,切换那令人讨厌的 Caps-Lock 值得失去代数属性,这些属性很难维持 以保持2D物理距离的方式处理其他边缘/角落情况... YMMV!

Prolog查询示例:

?- tipi([l,o,o,g,i,k,a],
        [k,i,i, f,u,j,a]).
true.

当我们在qwerty键盘上写“loogika”/“kiifuja”时,哪些键被按下了?看看!

before and after shift left, animated

1 个答案:

答案 0 :(得分: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是拼写错误;)

对于赏金,您可以在此表中使用曼哈顿距离。然后将该距离与Levenshtein距离的权重相结合。我提出了以下改编。我不确定它是否是一个真正的距离函数&#39;。

:-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))。这部分看起来很合适。