<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    莊周夢蝶

    生活、程序、未來
       :: 首頁 ::  ::  :: 聚合  :: 管理

    第六章:循環(huán)

    1、一定次數(shù)的循環(huán),看代碼,與Erlang一模一樣:

    loop(0).

    loop(N):-N>0,write('The value is: '),write(N),nl,

    M is N-1,loop(M).

    再看一個例子:

    output_values(Last,Last):- write(Last),nl,

    write('end of example'),nl.

    output_values(First,Last):-First=\=Last,write(First),

    nl,N is First+1,output_values(N,Last).

    2、循環(huán)直到條件滿足:

    go:-loop(start).

    loop(end).

    loop(X):-X\=end,write('Type end to end'),read(Word),

    write('Input was '),write(Word),nl,loop(Word).

    通過;/2謂詞,可以改寫為:

    loop:-write('Type end to end'),read(Word),

    write('Input was '),write(Word),nl,

    (Word=end;loop).


    3、使用repeat謂詞,這個謂詞名稱是典型的用詞不當(dāng),repeat并不重復(fù)任何東西,它僅僅是在任何時候執(zhí)行的時候都是success。那么當(dāng)回溯到repeat的時候,因為它是成功的,那么就要繼續(xù)從left->right的求值目標(biāo),直到后續(xù)的某個目標(biāo)滿足為止,例如:

    get_answer(Ans):-

    write('Enter answer to question'),nl,

    repeat,write('answer yes or no'),read(Ans),

    valid(Ans),write('Answer is '),write(Ans),nl.

    valid(yes). valid(no).

    這個程序檢測輸入,要求玩家必須輸入yes或者no才算結(jié)束,在repeatvalid(Ans)之間,如果沒有輸入yes或者no,將循環(huán)多次,直到valid(Ans)目標(biāo)被滿足(也就是輸入yes或者no)。回溯到repeat的時候,總是成功,那么就繼續(xù)求值后續(xù)的目標(biāo)write('answer yes or no'),read(Ans),repeat左邊的部分永遠(yuǎn)不會被回溯到。


    4fail謂詞,fail謂詞求值總是fail,因此強迫回溯開始,例如下面的例子:

    dog(fido).

    dog(fred).

    dog(jonathan).

    all_dogs:-

    dog(X),write(X),write(' is a dog'),nl,fail.

    all_dogs.


    謂詞all_dogs用于查詢數(shù)據(jù)庫中所有的dog,注意,最后的all_dogs.必須存在,不然all_dogs.在查找完所有的dog之后將總是fail


    第六章:預(yù)防回溯

    1cut謂詞:用于中止回溯,也可用!號表示。例如下面的例子:

    classify(0,zero).
    classify(N,negative):-N<0.
    classify(N,positive).


    用于檢驗?zāi)硞€數(shù)是正、負(fù)或者零。執(zhí)行:

    classify(-4,X).
    X = negative ;
    X = positive

    由于不能中止回溯,當(dāng)classify(N,negative):-N<0.執(zhí)行后,后續(xù)的也將執(zhí)行,當(dāng)然,你可以修改為:

    classify(0,zero).
    classify(N,negative):-N<0.
    classify(N,positive):-N>0.

    如果用cut謂詞更好:

    classify(0,zero):-!.
    classify(N,negative):-N<0,!.
    classify(N,positive).

    盡管一些程序可以不通過cut謂詞進(jìn)行修改,但是有一些程序(特別是當(dāng)一個謂詞調(diào)用另一個謂詞的時候)卻是不得不借住cut謂詞來中止回溯,才能實現(xiàn)正確的行為。

    cut的另一個用途就是確定通常情況下以外的異常,與fail搭配使用,我們知道fail強迫回溯開始

    例如有以下事實:

    bird(sparrow).
    bird(eagle).
    bird(duck).
    bird(crow).
    bird(ostrich).
    bird(puffin).
    bird(swan).
    bird(albatross).
    bird(starling).
    bird(owl).
    bird(kingfisher).
    bird(thrush).



    假設(shè)ostrich不能fly,我們的can_fly謂詞可能實現(xiàn)為:

    can_fly(ostrich):-fail.
    can_fly(X):-bird(X).

    但是由于fail強制回溯,那么can_fly(ostrich).還是成功,怎么辦呢?用cut:

    can_fly(ostrich):-!,fail.
    can_fly(X):-bird(X).

    cut中止了回溯。



    第8章:改變Prolog數(shù)據(jù)庫

    1、改變數(shù)據(jù)庫:加入和刪除語句

    如果刪除和加入語句僅僅靠consult和reconsult謂詞是低效,因此Prolog提供了BIPs用于刪除或者增加數(shù)據(jù)庫中的語句。

    如果一個謂詞可以被assertz, retract等BIPs修改,那么它必須聲明是動態(tài)的,否則Prolog將報錯。動態(tài)聲明必須放在謂詞聲明的前面,最好放在整個程序的前面,聲明方式如下:

    dynamic(mypred/3).

    這就將mypred/3謂詞聲明為動態(tài),可用BIPs進(jìn)行增刪了。

    1)增加語句,通過謂詞assertz/1和asserta/1,兩者的區(qū)別在于:前者將語句加入相應(yīng)謂詞的后面,而后者將語句加入相應(yīng)謂詞的開始處。例如:

    ?-assertz(dog(fido)).
    ?-assertz((go:-write('hello world'),nl)).

    ?-assertz(dog(X)).
    ?-assertz((go(X):-write('hello '),write(X),nl)).



    2) 刪除語句,也有兩個謂詞:retract/1和retractall/1,兩者的區(qū)別在于:前者接受一個參數(shù),并且是一條語句,刪除數(shù)據(jù)庫中第一條與該語 句匹配的語句;后者僅接受語句的head部分,用于刪除所有的滿足該head的語句。例如,假設(shè)數(shù)據(jù)庫中有如下語句:

    dog(jim).
    dog(fido).
    dog(X).

    執(zhí)行

    ?-retract(dog(fido)).

    刪除數(shù)據(jù)庫中的第2條語句,執(zhí)行

    ?-retract(dog(X)).

    卻是刪除dog(jim).因為這是第一條與(dog(X)匹配的語句,而最后的dog(X).反而得到保留。



    retractall(mypred(_,_,_)).刪除所有的mypred/3謂詞語句。

    retractall(parent(john,Y)).刪除所有的第一個參數(shù)的john的parent/2語句。

    retractall(mypred).刪除所有的mypred/0謂詞。


    2、維護(hù)事實庫,利用文件讀寫IO謂詞,和本章介紹的增刪謂詞,就用文本文件維護(hù)事實庫了,具體例子不說了。



    第9章:列表處理

    1、list在Prolog中是以[]包括的,以,號隔開的term組成,例如[a,b,c,d],空列表就是[]。了解過Erlang或者scheme的朋友,應(yīng)該對列表很熟悉。Erlang中的列表與Prolog中的列表概念一脈相承。

    2、這一章,真沒啥好細(xì)談的,列幾個BIPs吧

    1)member,判斷元素是否在列表中

    ?- member(a,[a,b,c]).
    yes

    ?- member(mypred(a,b,c),[q,r,s,mypred(a,b,c),w]).

    yes

    如果member的第一個參數(shù)是未綁定的變量,那么該變量將從左到右依次綁定列表中的元素。

    2)length謂詞,確定列表長度,第2個參數(shù)如果是變量,將變量綁定為列表參數(shù),如果是數(shù)字,就將該數(shù)字與長度比較,相等則success,否則fail。

    ?- length([a,b,c,d],X).
    X = 4

    ?- length([a,b,c],3).
    yes

    ?- length([a,b,c],4).
    no

    3)reverse謂詞,如果兩個變量都是list,就判斷是否互相倒序,如果一個是變量,一個是list,就將變量綁定為list的倒序:

    ?- reverse([1,2,3,4],L).
    L = [4,3,2,1]
    ?- reverse(L,[1,2,3,4]).
    L = [4,3,2,1]

    ?- reverse([1,2,3,4],[4,3,2,1]).
    yes

    4)append謂詞,三個參數(shù),如果前兩個是list,第三個為變量,那么將變量綁定為兩個list合并連接的列表:

    ?- append([1,2,3,4],[5,6,7,8,9],L).
    L = [1,2,3,4,5,6,7,8,9]
    ?- append([],[1,2,3],L).
    L = [1,2,3]


    如果前兩個參數(shù)包括變量,第三個是列表,那么將回溯尋找所有可能的列表組合:

    ?- append(L1,L2,[1,2,3,4,5]).
    L1 = [] ,
    L2 = [1,2,3,4,5] ;
    L1 = [1] ,
    L2 = [2,3,4,5] ;
    L1 = [1,2] ,
    L2 = [3,4,5] ;
    L1 = [1,2,3] ,
    L2 = [4,5] ;
    L1 = [1,2,3,4] ,
    L2 = [5] ;
    L1 = [1,2,3,4,5] ,
    L2 =[] ;

    no


    5) findall/3謂詞比較有趣,有點類似select的概念,它有三個參數(shù),第一個參數(shù)是一個變量或者帶變量的表達(dá)式,用于確定想要find并且 collect的元素結(jié)構(gòu),第二個參數(shù)是一個goal,用于執(zhí)行數(shù)據(jù)庫中是否有匹配項,第三個參數(shù)是變量,用于綁定最后收集到的匹配的元素列表,例子:

    假設(shè)我們已經(jīng)如下事實:

    person(john,smith,45,london).
    person(mary,jones,28,edinburgh).
    person(michael,wilson,62,bristol).
    person(mark,smith,37,cardiff).
    person(henry,roberts,23,london).



    那么執(zhí)行:

    findall(S,person(_,S,_,_),L).

    將返回:

    L = [smith,jones,wilson,smith,roberts]

    L收集了所有person的姓。如果執(zhí)行:

    ?- findall([Forename,Surname],person(Forename,Surname,_,_),L).


    將返回所有person的姓名組成的列表的列表:

    L = [[john,smith],[mary,jones],[michael,wilson],[mark,smith],[henry,roberts]]


    這是個非常有用的謂詞。



    第10章:字符串處理

    1、單引號括起來的atom就是字符串,又一個Erlang沿用Prolog的典型,字符串本質(zhì)上就是anscii碼組成的列表,列表跟字符串可以互相轉(zhuǎn)化,通過name/2謂詞:

    ?- name('Prolog Example',L).
    L = [80,114,111,108,111,103,32,69,120,97,109,112,108,101]

    ?-name(A,[80,114,111,108,111,103,32,69,120,97,109,112,108,101]).
    A = 'Prolog Example'


    2、常用謂詞,一般的Prolog系統(tǒng)其實都有字符串?dāng)U展謂詞,這里提供基本的實現(xiàn):

    1)連接字符串:

    join2(String1,String2,Newstring):-
       name(String1,L1),name(String2,L2),
       append(L1,L2,Newlist),
       name(Newstring,Newlist).

    轉(zhuǎn)成列表,通過append連接成新的列表,再轉(zhuǎn)成字符串。

    2)Trim謂詞,去除前后空格字符:

    trim([A|L],L1):-A=<32,trim(L,L1).
    trim([A|L],[A|L]):-A>32.

    trim2(L,L1):-
    reverse(L,Lrev),trim(Lrev,L2),reverse(L2,L1).

    trim3(L,L1):-trim(L,L2),trim2(L2,L1).
    trims(S,Snew):-name(S,L),trim3(L,L1),name(Snew,L1).

    真是麻煩吶,與join2是同樣的套路。

    3)讀入一行的readline謂詞:

    readline(S):-readline1([],L),name(S,L),!.
    readline1(Oldlist,L):-get0(X),process(Oldlist,X,L).
    process(Oldlist,13,Oldlist).
    process(Oldlist,X,L):-
      append(Oldlist,[X],L1),readline1(L1,L).



    第11章:高級特性


    1、操作符的擴展,通過op/3謂詞(略)

    2、term的處理,比較有趣的=..操作符,例如:

    X=..[member,A,L].

    將X綁定為member(A,L).

    X=..[colour,red].

    X綁定為color(red),=..稱為univ操作符(摘要操作符?),用于列表和term之間的相互轉(zhuǎn)化,反過來:

    ?- data(6,green,mypred(26,blue))=..L.

    L將綁定為

    L = [data,6,green,mypred(26,blue)]



    3、call/1謂詞,接受一個call term參數(shù),類似目標(biāo)執(zhí)行,例如:

    call(write('Hello world')).

    輸出:

    Hello worldyes


    可執(zhí)行多個term:

    ?-call(write('Hello world'),nl).

    Hello world

    yes


    call跟=..聯(lián)合調(diào)用:

    ?- X=..[write,'hello world'],call(X).
    hello worldX = write('hello world')



    4、functor/3謂詞:當(dāng)?shù)谝粋€參數(shù)是atom或者compound term或者某個綁定了類似值的變量,第二和第三個參數(shù)是未綁定變量,那么第二個參數(shù)變量將綁定為第一個參數(shù)的functor,第三個參數(shù)變量綁定為第一個參素的arity,舉例子說明:

    ?- functor(write('hello world'),A,B).
    A = write ,
    B = 1

    ?- functor(start,F,A).
    F = start ,
    A = 0

    ?- functor(a+b,F,A).
    F = + ,
    A = 2

    顯然,atom的arity是0。反過來,如果第一個參數(shù)是未綁定變量,后兩個參數(shù)已知:

    ?- functor(T,person,4).
    T = person(_42952,_42954,_42956,_42958)
    ?- functor(T,start,0).
    T = start


    5、arg/3謂詞,根據(jù)第一個參數(shù)數(shù)值,取第二個參數(shù)term的相應(yīng)位置的參數(shù),例如:

    ?- arg(3,person(mary,jones,doctor,london),X).
    X = doctor

    X綁定為person(mary,jones,doctor,london)的第3個參數(shù)。

    主站蜘蛛池模板: 日韩色日韩视频亚洲网站| 最近最好的中文字幕2019免费| 亚洲JIZZJIZZ妇女| 亚洲人成电影在线天堂| 亚洲成人高清在线| 国内精品免费视频自在线| 一区二区三区观看免费中文视频在线播放 | 一出一进一爽一粗一大视频免费的| 亚洲午夜一区二区电影院| 亚洲无人区一区二区三区| 国产免费午夜a无码v视频| 毛片高清视频在线看免费观看| 十八禁无码免费网站| 中国一级全黄的免费观看| 无套内谢孕妇毛片免费看看| 亚洲综合激情五月色一区| 亚洲日本香蕉视频观看视频| 久久精品国产亚洲香蕉| 中文字幕亚洲一区二区三区| 又大又黄又粗又爽的免费视频 | 亚洲一区二区三区影院 | 亚洲AV无码一区二区乱子伦| 亚洲日本韩国在线| 国产免费观看青青草原网站| 最新仑乱免费视频| 成人毛片18岁女人毛片免费看 | 亚洲一级毛片视频| 亚洲国产视频一区| 亚洲人成伊人成综合网久久| 久久精品国产亚洲av麻豆小说| 亚洲人成图片小说网站| 久久久久亚洲精品中文字幕| 亚洲精品99久久久久中文字幕 | 老汉精品免费AV在线播放| 少妇性饥渴无码A区免费| 91精品全国免费观看青青| 中文无码日韩欧免费视频| 中文在线观看国语高清免费| XXX2高清在线观看免费视频| 国产高清对白在线观看免费91| 国产成人1024精品免费|