2013-03-09 134 views
2

我想写一个Prolog的谓词,需要一个词,转变它向左或向右的键盘上...序言:移文本左,右键盘

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


例子。让我们在键盘上将“loogika”一词移到左边!

需要注意的是,如果我们的keyboard layoutqwerty, 我们打一个边缘当左移一个。我们可以处理与 不同的方式,但看起来每个“解决方案”有它自己和上 - 下方。

那么我们该怎么做?让左移一个Lock,而是留一个。 IMO,切换那个讨厌的大写锁定值得失去的代数特性,这是很难坚持的时候 处理在保留2D物理距离的方式与其他边缘/角落的情况下...因人而异!

样品Prolog的查询:

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

当我们写 “loogika”/ “kiifuja” 上的QWERTY键盘当中去按键?看,看!

before and after shift left, animated

+2

请张贴一些例子输入和预期的结果 - 正面和负面的。 – 2013-03-09 17:23:41

+1

@repeat做我的答案,回答你的赏金问题? – user27815 2015-10-09 13:44:54

回答

-2

您可以使用以下代码左移。

shift(L1,L2):- 
     del(L1,L3,X), 
     add(L3,X,L2). 

    del([X],[],X). 

    del([Head|Tail],[Head|L],X):- 
     del(Tail,L,X). 

    add(L3,X,[X|L3]). 

输出是:

shift([1,2,3,4,5],A). 

A=[5,1,2,3,4] 
+1

这绝对是**而不是** OP所要求的! – repeat 2015-08-19 10:31:03

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距离的权重结合起来。我提出了以下改编。我不确定它是否是“实际距离函数”。

:-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))。这看起来适合于其中的一部分。