; Predejte tento soubor funkci lisp2prolog: ; (lisp2prolog "samples.lisp") (defun factorial (X) (cond ((= X 0) 1) ((* X (factorial (- X 1)))))) ; FACTORIAL(0,1). ; FACTORIAL(X,T3) :- ; T1 is X - 1, ; FACTORIAL(T1,T2), ; T3 is X * T2. (defun factorialTR (X TMP) (cond ((= X 0) TMP) ((factorialTR (- X 1) (* X TMP))))) ; FACTORIALTR(0,TMP,TMP). ; FACTORIALTR(X,TMP,T3) :- ; T1 is X - 1, ; T2 is X * TMP, ; FACTORIALTR(T1,T2,T3). ; Takto vypada kod v Prologu ve "vnitrni forme" pred vytistenim. ; ; (((PRINT-VALUE . TMP) NIL (X 0 TMP TMP) ((FACTORIALTR (PRINT-PARAMS))) ; (X TMP)) ; ((PRINT-VALUE . T3) NIL (X X TMP TMP T1 T1 T2 T2 T3 T3) ; ((FACTORIALTR (PRINT-PARAMS)) ; ((PRINT-VALUE . T1) " is " (PRINT-VALUE . X) " - " 1) ; ((PRINT-VALUE . T2) " is " (PRINT-VALUE . X) " * " ; (PRINT-VALUE . TMP)) ; (FACTORIALTR "(" (PRINT-VALUE . T1) "," (PRINT-VALUE . T2) "," ; (PRINT-VALUE . T3) ")")) ; (X TMP))) (defun cond_in_cond (X Y) (cond ((= X 1) 2) ((= (+ 3 1) X) (cond ((= Y 5) 7) ((= Y 8) (* 9 (+ Y 7))))))) ; COND_IN_COND(1,Y,2). ; COND_IN_COND(X,5,7) :- ; X is 3 + 1. ; COND_IN_COND(X,8,T1) :- ; X is 3 + 1, ; T1 is 9 * (8 + 7). (defun cond_as_operand (X Y) (cond ((= X 1) 2) ((= (+ 3 1) X) (+ 11 (cond ((= Y (* 3 5)) 7) ((= Y 8) (* 9 (+ Y 7)))))))) ; COND_AS_OPERAND(1,Y,2). ; COND_AS_OPERAND(X,Y,T1) :- ; X is 3 + 1, ; Y is 3 * 5, ; T1 is 11 + 7. ; COND_AS_OPERAND(X,8,T2) :- ; X is 3 + 1, ; T2 is 11 + 9 * (8 + 7). (defun list_using_conses (X Y Z) (cons X (cons Y (cons Z nil)))) ; LIST_USING_CONSES(X,Y,Z,[X, Y, Z]). (defun cons_example (X) (= X (cons (cons 1 2) (cons (cons 3 4) 5)))) ; CONS_EXAMPLE([[1|2], [3|4]|5]). (defun car_cons_cons_1_2_3 () (car (cons (cons 1 2) 3))) ; CAR_CONS_CONS_1_2_3([1|2]). (defun my_cdadr (X) (cdr (car (cdr X)))) ; MY_CDADR([T1, [T5|T6]|T4],T6). ; ?- A=[B|C], C=[D|E], D=[F|G], write(G). ; _G170 ; ; A = [_G157, [_G169|_G170]|_G164] ; B = _G157 ; C = [[_G169|_G170]|_G164] ; D = [_G169|_G170] ; E = _G164 ; F = _G169 ; G = _G170 (defun eq_cons_nil_7 (X) (eq X (cons nil 7))) ; EQ_CONS_NIL_7([[]|7]). ; Nyni uvedu nekolik prikladu na kterych si prekladac "vylame zuby". ; Nasleduje-li vice vyrazu za sebou, ve kterych se testuji podminky, neni ; zrejme, co dat na vystup. Navratova hodnota funkce problem1 vubec nezavisi ; na splneni prvniho condu. Co s tim? (defun problem1 (X) (cond ((= X 11) 111) ((= X 12) 112)) (cond ((<= X 21) 211) ((= X 22) 212))) ; PROBLEM1(11,211) :- ; 11 > 21. ; PROBLEM1(11,212) :- ; 11 = 22. ; PROBLEM1(12,211) :- ; 12 > 21. ; PROBLEM1(12,212) :- ; 12 = 22. ; Problemy nastanou, pokud v pravidle zavolame funkci, jejiz navratova hodnota ; v LISPu je boolean. Prekladac by si musel pamatovat aritu predikatu ; a podle ni se rozhodovat, zda prida do parametru predikatu promennou ; pro navratovou hodnotu nebo bude navratova hodnota boolean skryta ; v nalezeni predikatu. ; To by vsak vyzadovalo dvojnasobne zpracovani zdrojoveho textu, nebot ; LISP kontroluje vse az za behu volani, coz umoznuje pouzit v definici funkce ; jinou funkci, ktera jeste neni definovana. (defun equals3 (X) (= X 3)) (defun problem2 (X) (cond ((= X 0) (equals3 X)))) ; EQUALS3(3). ; ; PROBLEM2(0,T1) :- ; EQUALS3(0,T1). ; Vsechny parametry funkce dostavaji stejny vstupni stav, zatimco ; v nasledujicim prikladu u funkce cons mel byt vstupni stav parametru ; definovan vystupnimi stavy predchoziho parametru. ; Nevim, zda by to ale nezpusobilo dalsi komplikace jako napriklad u problem1. (defun problem_append (LIST1 LIST2) (cond ((null LIST1) LIST2) ((cons (car LIST1) (problem_append (cdr LIST1) LIST2))))) ; PROBLEM_APPEND([],LIST2,LIST2). ; PROBLEM_APPEND([T1|T2],LIST2,[T1|T5]) :- ; PROBLEM_APPEND(T4,LIST2,T5), ; [T1|T2] = [T3|T4]. ; Krome problemu s volanim funkci vracejici boolean uvedenem jiz v problemu 2, ; je zde patrny rozdil LISPu a Prologu - prvni varianta condu neni v Prologu ; potreba. ; Navratova hodnota nil je nahrazena nenalezenim predikatu v Prologu. (defun problem_member (X LIST) (cond ((null LIST) nil) ((eq (car LIST) X)) ((problem_member X (cdr LIST))))) ; PROBLEM_MEMBER(X,[],[]). ; PROBLEM_MEMBER(X,[X|T2]). ; PROBLEM_MEMBER(X,[T3|T4],T5) :- ; PROBLEM_MEMBER(X,T4,T5).