close
 
撰寫一些prolog函數方便處理

/*
Prolog library
Jia-Yang Chen
補足List的不足,將兩個List做交集與聯集,尋找List中是否包含某值
isFind(+Thing,+Value)
isFind(+Thing,+Value,?Ans)
參數說明:Thing為一個List,Value是想要判斷的值,Ans為答案,Ans為yes代表存在一個Value在Thing這個List中,若為no則不存在,Ans為變數
findMany(+Thing,+Value,?Ans)
參數說明:Thing為一個List,Value是想要判斷的值,Ans為答案,Ans中的數值為在Thing中所找到的Value個數
intersectionOf(+Serial1,+Serial2,?AnsList)
參數說明:Serial1和Serial2型態為List,存放兩個集合,AnsList為交集後的結果,AnsList為變數
unionOf(+Serial1,+Serial2,?AnsList)
參數說明:Serial1和Serial2型態為List,存放兩個集合,AnsList為聯集後的結果,AnsList為變數
singleOf(+Serial,?AnsList)
參數說明:Serial型態為List,AnsList為變數,將Serial中的元素做單一化,AnsList為結果
delOf(+Serial,+Value,?AnsList)
參數說明:Serial型態為List,Value為所想要找的值,AnsList為濾掉後的結果
copyN(+Num,+Value,?AnsList)
參數說明:Num為要複製的次數,Value為要複製的值,AnsList為複製後的結果
inverse(+Serial,?AnsList)
參數說明:Serial型態為List,AnsList為Serial List反轉後的結果
sortOf(+Serial,?AnsList)
參數說明:Serial型態為List,AnsList為Serial List排序後的結果
*/

/*如果X不是變數則做一些事情,如果X是一個變數,初始化它*/
/*傳了一個變數進來,如果這個變數有值則我們做一些事情,否則設定值給他*/
/*利用這個方法可以讓傳入的東西同時具有變數與數值的特性*/
check(X):-
type(X,Y),Y =\= 0->print('please write some program for do something here'),nl;print('we will set zero to it'),X = 0 ,nl.

/*假若X有值,則將X加1後丟給Num,如果沒有值,則將X與Num設成0*/
add_one(X,Num):-
type(X,Y),Y == 1->Num is X+1,print('after add one the value is: '),print(Num),nl;X=0,Num=0.

/*prolog中一但變數被設定後便無法在設值,所以需額外設置變數使用*/
/*在prology中如何做錯誤處理,在沒有結果時,給適當的回應*/

/*下面的函式是搜尋某一個值是否在List之中,並判斷是否給予一個List
isFind([1,2,3],3,Ans).
==>Ans = yes.
*/

isFind(Thing,Value):-
isFind(Thing,Value,Ans),print(Ans).

isFind(Thing,Value,Ans):-
type(Thing,Y),Y == 6 ->len(Thing,C),find_value(Thing,C,Value,Ans);print('We need a list to find.').

find_value(Thing,Cnum,Value,Ans):-
Cnum == -1 ->Ans = yes;(
Cnum =\= 0 ->isValue(Thing,NewThing,Len,Value),find_value(NewThing,Len,Value,Ans);Ans = no).

isValue([H|T],T,Len,Value):-
H == Value-> Len = -1;
len(T,C),Len=C.

/*搜尋 END*/

/*找到多少個,得到某元素在某List中的個數
findMany([1,2,3,4,4,3,3],4,Ans).
==> Ans = 2.
*/

findMany(Thing,Value,Ans):-
list(Thing)->(
len(Thing,C),findCounter(Thing,C,Value,[]),ans(Ans),retractall(ans(X))
);print('we need a list.').

findCounter(Thing,Len,Value,Temp):-
Len =\= 0 ->(
isValue(Thing,NThing,Flag,Value),len(NThing,NLen),
findCounter(Flag,NThing,NLen,Value,Temp)
);len(Temp,X),assert(ans(X)).

findCounter(Flag,NThing,NLen,Value,Temp):-
Flag == -1 ->(
append([Value],Temp,NTemp),findCounter(NThing,NLen,Value,NTemp)
);findCounter(NThing,NLen,Value,Temp).
/*找到多少個End*/

/*取出List的第一個元素,並傳回剩下的元素個數與剩下的List*/

getValue([H|T],H,T,Len):-
len(T,C),Len = C.

/*取出List End*/

/*製作兩個小函數來處理List的交集與聯集*/
/*想法利用上面的功能,在List存在你想要的值,回答yes,否則no*/
/*兩個List取交極
intersectionOf([1,2,3],[2,3,4],Ans).
==> Ans=[2,3].
*/

intersectionOf(Serial1,Serial2,AnsList):-
list(Serial1)->(
list(Serial2)->(
len(Serial1,C1),len(Serial2,C2),intersectionDeal(Serial1,C1,Serial2,C2),ans(Serial),singleOf(Serial,AnsList),retractall(ans(X))
);print('The type of second argument is a List?')
);print('The type of first argument is a List?').
/*原始狀況(第一版)*/
intersectionOf_1(Serial1,Serial2,AnsList):-
list(Serial1)->(
list(Serial2)->(
len(Serial1,C1),len(Serial2,C2),intersectionDeal(Serial1,C1,Serial2,C2),ans(AnsList),retractall(ans(X))
);print('The type of second argument is a List?')
);print('The type of first argument is a List?').
/*原始狀況(第一版) End*/
intersectionDeal(Serial1,C1,Serial2,C2):-
C1 =\= 0 ->(
C2 =\= 0 ->(
intersection(Serial1,C1,Serial2,[])
);assert(ans([]))
);assert(ans([])).

intersection(Serial1,C1,Serial2,TempList):-
C1 =\= 0->(
getValue(Serial1,V1,NSerial1,NC1),findThing(Serial2,V1,TF),
intersectionSet(TF,V1,NSerial1,NC1,Serial2,TempList)
);assert(ans(TempList)).

intersectionSet(YorN,Value,NSerial1,NC1,Serial2,TempList):-
YorN == yes->(
intersectionDo(Value,TempList,NList),
intersection(NSerial1,NC1,Serial2,NList)
);intersection(NSerial1,NC1,Serial2,TempList).

intersectionDo(Value,AppendList,AnsList):-
append([Value],AppendList,AnsList).

/*交集End*/

/*兩個List取聯集,利用findValue(L1,V,Ans)
unionOf([1,2,3],[4,5,6],Ans).
==> Ans=[3,2,1,4,5,6].
*/

unionOf(Serial1,Serial2,AnsList):-
list(Serial1)->(
list(Serial2)->(
len(Serial1,C1),len(Serial2,C2),unionDeal(Serial1,C1,Serial2,C2),ans(Serial),singleOf(Serial,AnsList),retractall(ans(X))
);print('The type of second argument is a List?')
);print('The type of first argument is a List?').
/*原始狀況(第一版)*/
unionOf_1(Serial1,Serial2,AnsList):-
list(Serial1)->(
list(Serial2)->(
len(Serial1,C1),len(Serial2,C2),unionDeal(Serial1,C1,Serial2,C2),ans(AnsList),retractall(ans(X))
);print('The type of second argument is a List?')
);print('The type of first argument is a List?').
/*原始狀況(第一版) End*/
unionDeal(Serial1,C1,Serial2,C2):-
C1 =\= 0 ->(
C2 =\= 0 ->(
union(Serial1,C1,Serial2,Serial2)
);assert(ans(Serial1))
);C2 =\= 0->(
assert(ans(Serial2))
);assert(ans([ ])).

union(Serial1,C1,Serial2,TempList):-
C1 =\= 0->(
getValue(Serial1,V1,NSerial1,NC1),findThing(Serial2,V1,TF),
unionSet(TF,V1,NSerial1,NC1,Serial2,TempList)
);assert(ans(TempList)).

unionSet(YorN,Value,NSerial1,NC1,Serial2,TempList):-
YorN == no->(
append([Value],TempList,NList),
union(NSerial1,NC1,Serial2,NList)
);union(NSerial1,NC1,Serial2,TempList).

/*聯集End*/

/*單一化,如果在一個List中有多個元素重複,僅取一個
singleOf([1,2,1],Ans).
==>Ans=[1,2].
*/

singleOf(Serial,AnsList):-
list(Serial)->
len(Serial,Y),singleDo(Serial,Y,[ ]),
ans(AnsList),retractall(ans(X))
;print('we need a list.').

singleDo(Serial,Len,Temp):-
Len =\= 1 ->(
getValue(Serial,H,T,NLen),findThing(T,H,YorN),
singleDeal(YorN,H,T,NLen,Temp)
);append(Serial,Temp,NL),assert(ans(NL)).

singleDeal(YorN,H,T,NLen,Temp):-
YorN == no -> (
append([H],Temp,NList),singleDo(T,NLen,NList)
); singleDo(T,NLen,Temp).

/*單一化 End*/

/*如果Serial中有包含某值時,將某值殺掉,濾掉雜質
delOf([3,1,3,2,3],3,Ans).
==>Ans=[2,1].
*/


delOf(Serial,Value,AnsList):-
list(Serial)->
len(Serial,Len),
delDo(Serial,Value,Len),
ans(AnsList),retractall(ans(X))
;print('we need a list.').

delDeal(Serial,Value,Len,Temp):-
Len =\= 0->(
getValue(Serial,H,T,NLen),
Value =\= H ->(
append([H],Temp,NTemp),
delDeal(T,Value,NLen,NTemp)
);getValue(Serial,H,T,NLen),delDeal(T,Value,NLen,Temp)
);assert(ans(Temp)).

delDo(Serial,Value,Len):-
findThing(Serial,Value,YorN),
YorN = yes ->(
delDeal(Serial,Value,Len,[])
);assert(ans(Serial)).

/*濾掉某元素 End*/

/*排序,將一個List中的元素做排序
sortOf([8,2,5,3,7,2,5,2,3],Ans).
==>Ans = [2, 2, 2, 3, 3, 5, 5, 7, 8].
*/

sortOf(Serial,AnsList):-
list(Serial)->
sort(Serial,SortSerial),len(Serial,C1),len(SortSerial,C2),
sortDo(Serial,SortSerial,AnsList,C1,C2)
;print('we need a list.').

sortDo(Serial,SortSerial,AnsList,Len1,Len2):-
Len1 =\= Len2->(
sortDeal(Serial,SortSerial,Len2,AnsList,[])
);AnsList=SortSerial.

sortDeal(Serial,SortSerial,Len,AnsList,Temp):-
Len =\= 0 ->(
getValue(SortSerial,H,T,NLen),findMany(Serial,H,Ans),
copyN(Ans,H,TempList),append(TempList,Temp,NTemp),sortDeal(Serial,T,NLen,AnsList,NTemp)
);inverse(Temp,InverseTemp),AnsList=InverseTemp.

/*將某值複製N次後存入AnsList
copyN(2,'Hello',Ans).
==>
T = ['Hello', 'Hello'].
*/

copyN(Num,Value,AnsList):-
Num =\= 0 ->(
copyNN(Num,Value,[]),ans(AnsList),retractall(ans(X))
);AnsList=[ ].

copyNN(Num,Value,TempList):-
Num =\= 0 ->(
append([Value],TempList,NTemp),NNum is Num -1,copyNN(NNum,Value,NTemp)
);assert(ans(TempList)).

/*反轉,將原來的List順序顛倒
inverse([1,2,3],Ans).
==>Ans = [3,2,1].
*/

inverse(Serial,AnsList):-
list(Serial)->(
len(Serial,Len),
inverseDo(Serial,Len),ans(AnsList),retractall(ans(X))
);print('we need a list.').

inverseDo(Serial,Len):-
Len =\=0->(
inverseDeal(Serial,Len,[])
);assert(ans([])).

inverseDeal(Serial,Len,Temp):-
Len =\= 0 ->(
getValue(Serial,H,T,NLen),append([H],Temp,NTemp),inverseDeal(T,NLen,NTemp)
);assert(ans(Temp)).
arrow
arrow
    全站熱搜

    CJY0503 發表在 痞客邦 留言(0) 人氣()