程式語言─課堂作業
Prolog
- Prolog(Programming in Logic的縮寫)是一種邏輯編程語言
- 由法國馬賽大學所設計出來的程式語言。
- 以符號邏輯為基礎,且具有推理性的程式語言,在人工智慧的領域有很大貢獻。
Prolog練習與整理
- 規則與事實(rules and facts)
- 邏輯基底程式導向語言(邏輯導向程式語言) (logic-based programming language)
- 常數
- 整數
- 字元
- 小寫字母為開頭
- 變數
- 結構
- 格式:函數名稱(值1,值2,值3)
- 值也可以是一個結構
- 利用結構表示事實
- 學生fei就讀逢甲大學(fcu)
student(fei,school(fcu))
- 每一個值都可以是結構
student(person(fei,girl),school(fcu,taichung))
- 從上面的式子可以知道student、person、school都是結構
-
練習一
-
mother(ruby, tim). %ruby是tim的媽媽 father(andy, ruby). %andy是ruby的爸爸 parent(X, Y) :- father(X, Y). %parent(X,Y)條件須滿足father(X,Y) parent(X, Y) :- mother(X, Y). %parent(X,Y)條件須滿足mother(X,Y)
%grandparent函式輸入X,Z需同時滿足parent(X,Y)和parent(Y,Z) grandparent(X,Z) :- parent(X,Y), parent(Y,Z). ------------------------------------- ?-grandparent(andy,tim) True
-
-
練習二
-
% 速度(車種,數值) speed(toyota, 100).
speed(honda, 105). speed(benz, 120). speed(mazda,110).% 花費時間(車種,數值) time(toyota, 21). time(honda, 22). time(benz, 23). time(mazda, 24).
% 計算距離函式 % 找出X的速度以及花費時間 % 輸出Y為距離 distance(X, Y) :-speed(X, Speed), time(X, Time),Y is Speed * Time. ------------------------------------- ?- distance(toyota, Distance). Distance = 2100
?-trace, (distance(toyota, Distance)). Call:distance(toyota, 12130) Call:speed(toyota, 12326) Exit:speed(toyota, 100) Call:time(toyota, 12326) Exit:time(toyota, 21) Call:12130 is 10021 Exit:2100 is 10021 Exit:distance(toyota, 2100) Distance = 2100
-
-
函式庫:list,List Manipulation(列表操作)
-
member(?Elem, ?List)
- 判斷元素是否在列表內
-
?- member(a,[a,b,c]). true
?- member(list(a,b,c),[t,e,v,list(a,b,c),d]). true
-
length(?List, ?Int)
- 回傳列表長度
- 第2個參數
- 如果是變數,將變數綁定為列表參數
- 如果是數字,就將該數字與長度比較,相等則True,否則False。
?- length([a,b,c,d],X). X = 4
?- length([a,b,c],3). true
?- length([a,b,c],4). false
-
reverse(?List1, ?List2)
- 如果兩個變數都是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]). true
-
append(?List1, ?List2, ?List1AndList2)
- 如果前兩個是list,第三個為變數,那麼將變數綁定為兩個list合併連接的列表
- 如果前兩個參數包括變量,第三個是列表,那麼將回溯尋找所有可能的列表組合
?- append([1,2,3,4],[5,6,7,8,9],L). L = [1, 2, 3, 4, 5, 6, 7, 8, 9] % 列出L1,L2所有排列組合 ?- 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 = []
-
Prolog Deficiencies心得報告
- Prolog對新手來說相當困難,跟C語言等語言的思考模式較不相同。
- Prolog比較抽象,編譯器很難加以優化。
- Prolog並不直觀,執行效率差。
- Prolog是處理符號和非數值運算之程式語言,因此對於數值運算無法解決"
Prolog 期中考題目
% 判斷參數是否為列表內的第一個元素 % 如果不是第一個元素,查看列表其他元素 % 取出第一個元素後,剩下的元素成新的列表 % 依序查看參數是否為列表內的第一個元素 member(E, [E|_]) :- !. member(E, [_|List]) :- member(E, List). --------------------- ?- member(a, [b,c,a,d]). true ?- trace, (member(a, [b,c,a,d])). Call:member(a, [b, c, a, d]) % 因a不等於b,因此查看下一個元素 Call:member(a, [c, a, d]) % 因a不等於c,因此查看下一個元素 Call:member(a, [a, d]) % 因a等於a,因此結束呼叫 Exit:member(a, [a, d]) % 因已找到a,因此結束呼叫 Exit:member(a, [c, a, d]) % 因已找到a,因此結束呼叫 Exit:member(a, [b, c, a, d]) % 因已找到a,因此結束呼叫 true % 因已找到a,故為true
Lisp
- 舉一個例子,寫一個函數來回傳小於 n 的數字總和,用Lisp和C來比較
; Lisp / C / (defun sum (n) int sum(int n){ (let ((s 0)) int i, s = 0; (dotimes (i n s) for(i = 0; i < n; i++) (incf s i)))) s += i; return(s); }
Lisp 練習
輸出練習
(write-line "Hello World") ;輸出Hello World (write (+ 7 9 11));輸出11+7+9=27
使用前綴符號
- 比如說:a * ( b + c ) / d
- 在Lisp語言內要寫:(/ (* a (+ b c) ) d)
(write(+ (* (/ 9 5) 60) 32));輸出(60*9/5)+32=140
Lisp期中考
(DEFINE (compose f g) % 接受 f 和 g 函數. (LAMBDA (x) (f (g x)))) , % 將 f ( g x) 設為一個匿名函數. ((compose CAR CDR) '(a b c)) , % 將資料 (a b c) 透過 (compose f g) 轉為 (LAMBDA (c) (a (b c))) . ((DEFINE (adder alist) % 定義 (adder alist) 為以下的判斷式. (COND ((NULL?alist) 0) % alist 若為為空,則回傳 0 . (ELSE (EVAL (CONS '+ alist))))) , % 否則將 alist 的所有內容加總. % (使用cons把 ""+"" 和 ""alist"" 合併為 ""+ alist"" ,再使用 eval 將 ""+ alist"" 從資料型態轉成函數.) (adder '(3 4 5 6 2)) ? % 判斷 alist 是否為零,若非為零則將 alist 加總,再回傳計算過後的結果.
Erlang
Erlang is a general-purpose concurrent programming language and runtime system. The sequential subset of Erlang is a functional language, with strict evaluation, single assignment, and dynamic typing. ~維基百科
- Erlang有許多近似Pure Functional Language的特性
- 優點
- 建構並行(Concurrent)
- 分散(Distributed)
- 容錯 (Fault-tolerance)的系統
- 缺點
- 內建函式庫的貧乏
- 對Unicode支援度低
- 缺乏良好的IDE及Debug Tool
Java (Exception and Event Handling)
- 例外(Exception):任何不正常的事件,不論是否有錯誤,都可以通過硬體或軟體檢測到,並且可能需要特殊處理。
- 異常處理程序(Exception handler):處理異常的程式碼單元。
- 引發異常(Raising an exception):發生與異常相關的事件時。
- 禁用異常(Disabling an exception):忽略某些硬體可檢測的異常。
- 繼續(Continuation):控製程序程式碼或程序之外的程序中的某處可能會終止。
- 完成(Finalization):無論子程序如何停止,都可以完成一些運行。
- 內置異常(Built-in exception):不是由使用者做出的異常,而是默認的。
Java提供了豐富的異常處理機制,與C語言相同,Java的異常處理也是包含在try, catch, finally三個塊中的,常見的異常處理方式如下:
try{ // code 可能會產生異常 } catch(IOException e){ // IOException輸入輸出異常,當產生異常被偵測之後,catch內的code會被執行 } finally { // 無論是否有異常,這裡的code都會執行 }
(圖轉載至openhome)
Java的異常處理程序與C ++的異常處理程序具有相同的形式,只是每個catch必須有一個參數,這個參數均應是java.lang.Throwable的子類別。其中,主要分為兩大子類別:
- java.lang.Error: 其子類別表示了Java虛擬機的異常
- java.lang.Exception: 其子類別表示了程序運行中的異常
Exception的子類還可以分為兩類:
- java.lang.RuntimeException: 其子類表示了運行中的異常,該異常可以不被catch,編譯器也能通過。該子類表示的異常,均應該在原始碼中避免,比如數組範圍的超出等等。
- 非RuntimeException: 其子類表示了程序中不可避免的異常,如文件不存在的FileNotFoundException異常,該異常必須被catch掉或者是在函數頭處聲明。
finally子句放在完整的try結構之後的處理程序列表的末尾。這個結構的語義如下:
- 如果try子句不引發異常,finally子句在try結構之後繼續執行之前被執行。
- 如果try子句拋出一個異常,並被後面的處理程序捕獲,finally子句在處理程序完成執行後執行。
- 如果try子句拋出一個異常,但是它並沒有被try結構之後的處理程序捕獲,finally子句在異常傳播之前被執行。
如果在程式當中需要拋出異常,應使用throw關鍵字:
if(!file.exists()) { throw new FileNotFoundException(""檔案不存在""); }
如果是方法(method)裡拋出異常,應使用關鍵字throws:
public void get() throws Exception{ }
Java (Concurrency)
平行(Parallelism)與併行(Concurrency)的差別如下:
- 多個任務分配到一個CPU核心,在取得的CPU時間片段中交互執行,稱之為併行(Concurrency)。
- 一個任務可被分成多個子任務並分配到不同的CPU核心同時執行,稱之為平行(Parallelism)。
平行與併行的講解:
- Concurrency:多個任務(tasks)同時處理。而併行的相反則為序列化處理,也就是要等一件任務完成才能開始執行另外一件任務。
- Parallelism:一個任務分拆為數個子任務來同時執行。
平行和併行是分別獨立的概念,彼此並沒有依賴關係,有平行不一定有併行,反之亦然。
簡單舉例
(支援Concurrency)你吃飯吃到一半,電話來了,你停了下來接了電話,接完後繼續吃飯,這說明你支持Concurrency。 (支援Parallelism)你吃飯吃到一半,電話來了,你一邊打電話一邊吃飯,這說明你支持Parallelism。 (都不支援)你吃飯吃到一半,電話來了,你一直到吃完了以後才去接,這就說明你不支持Parallelism也不支持Concurrency。