楓葉/深入瞭解楓葉
楓葉有三個主要元件:使用者介面、核心和庫。
最近的楓葉版本包含三個使用者介面可執行檔案(對於大多數作業系統),兩個圖形使用者介面(GUI):標準 GUI 和經典 GUI,以及一個命令列(基於字元)介面。
標準 GUI 是一個 Java 應用程式,而經典 GUI 是一個本地應用程式。
核心(直譯器)處理楓葉的基本功能(例如基本資料結構、輸入/輸出、整數和有理數運算、簡單的多項式計算和基本化簡)。它是用 C 和 C++ 編寫的。在啟動楓葉會話時,它會被完整載入。
庫包含系統的大多數例程。它是用楓葉高階程式語言編寫的。這是一種解釋型語言。它不會被編譯。它的例程儲存在 .mla 檔案中。根據需要將庫例程載入到系統中。這種設計的模組化允許使用者消耗與實際使用的代數功能成比例的計算機資源。
一些數值也用 C 和 C++ 實現,並透過楓葉的外部呼叫機制由庫例程動態訪問。
除了內建函式外,每個例程的楓葉原始碼都可以顯示。
楓葉有一個全面的線上幫助設施。
對使用者來說,楓葉就像一個“互動式計算器”。
楓葉系統的輸入由一系列語句組成,語句之間用語句分隔符(分號 ; 和冒號 :)分隔。系統以互動模式執行,在輸入時執行語句。
主程式讀取輸入,呼叫解析器,然後為遇到的每個完整語句呼叫語句求值器。
楓葉中有八種類型的語句:賦值語句、表示式、讀取語句、儲存語句、選擇語句、重複語句、空語句和退出語句。
楓葉將讀取無限數量的語句;它的正常結束是透過退出語句的求值(而不是解析)實現的。
解析器和一些基本內部函式負責構建楓葉內部使用的所有資料結構。
楓葉語言被設計為互動式使用。
一個統一的觀點是,楓葉中的所有變數都是程式設計變數。那些用作數學符號的變數,其值為它們自己的名稱;那些用作程式設計變數的變數,其值為分配給它們的其它東西。
楓葉字元集包含字母、數字和特殊字元。
標記由關鍵字、程式語言運算子、字串、自然整數和標點符號組成。
數字、字串和名稱是楓葉中最簡單的物件。
自然整數是任何一個或多個數字的序列。楓葉中的數字常量(整數、有理數和浮點數)是由自然整數使用程式語言運算子形成的。自然整數的長度,因此整數、有理數和浮點數的長度是任意的(即,長度限制是系統相關的,但通常遠大於使用者會遇到的長度)。
名稱是可以分配值的字元序列,因此它表示變數。任何表示式都可以分配給名稱。如果未將值分配給名稱,則它代表它自身。
名稱的最簡單形式是字母(a-z,A-Z)後跟零個或多個字母、數字(0-9)和下劃線(_)。即,楓葉區分大小寫字母。因此,名稱 pvar、Pvar、PVAR、pVaR 都引用不同的變數。名稱的最大長度是系統相關的。在 32 位平臺上,它是 524,271 個字元;在 64 位平臺上,它是 34,359,738,335 個字元。在 16 位平臺上是 499 個字元?
名稱的另一種形式是下劃線後跟零個或多個字母、數字和下劃線。這種名稱由楓葉用作全域性變數名稱,實際上保留供庫程式碼使用。例外的是以 _Env 開頭的名稱,它們被認為是環境變數。
一些其他名稱已由楓葉定義,要麼作為關鍵字(例如 if、then、else、do、quit),要麼作為命令名稱(例如 sin、cos、ln、diff、int),環境變數(例如 Digits、UseHardwareFloats、printlevel、Rounding),要麼作為預定義的數學常量(例如 Pi、I、GAMMA)。
因此,使用者應避免使用這些名稱。
名稱也可以透過將任何字元序列括在反引號字元對(左單引號)(` `)中來形成。例如
>`This is a name`;
字串是具有固定值的字元序列(它不能分配任何其他值)。字串的最大長度是系統相關的。在 32 位平臺上,它是 268,435,439 個字元;在 64 位平臺上,它是 34,359,738,335 個字元。
字串透過將任何字元序列括在雙引號字元對(" ")中來編寫。例如
>"This is a string";
表示式是楓葉語言中的基本實體。
每個楓葉表示式都儲存在一個數據結構中。
集合是表示式的無序集合。任何有效的楓葉表示式都可以包含在集合中。
楓葉中的每個物件都與它相關聯的型別。
型別由計算的域或子域定義。
楓葉中未賦值的名稱,由於沒有宣告,可以代表任何資料型別。
在楓葉中,型別是任何由 type 函式識別的表示式,它會導致 type 函式從一些表示式集中返回 true,否則返回 false。
型別可以是簡單型別或結構化型別。它們可以在楓葉中預定義,也可以由使用者定義。簡單型別是由單個名稱標識的,而結構化型別可以由簡單型別或其他結構化型別組成。結構化型別也可以遞迴地定義。
請記住,雖然你總是可以查詢物件的型別,但在楓葉中沒有辦法規定某個變數始終為某種型別。
一般來說,楓葉試圖保留資料的型別。
楓葉中物件的型別(通常與物件實際上是什麼樣的資料結構有關)和屬性(與物件可以代表的數學物件有關)之間存在根本區別。
型別和屬性之間有區別。*物件* *具有*與其本質相關的型別——它不能被賦予或“分配”或宣告為某種型別。
名稱或符號可以被賦予屬性。一些比符號更復雜的物體也可以被賦予這樣的屬性。許多屬性的名稱與型別相同。“float”是一個屬性和一個型別。符號永遠不可能是 float、integer 等型別的,但它可以被賦予該屬性。
程式語言的運算子有三種類型:二元運算子、一元運算子和零元運算子。
連線符或|| 運算子(以前稱為點運算子)是 Maple 中的命名運算子——它生成全域性名稱。
ditto 運算子% 用於回撥最後一個結果,它在過程內部是區域性的,但 Maple 會完全對其進行評估。
@ 是函式組合運算子。
@@ 是重複函式組合運算子
在 Maple 中,語句通常在當前環境中儘可能遠地進行評估。
在 Maple 中,表示式的評估通常是在完全的遞迴評估模式下執行的。
無論是在過程內還是在互動式級別,Maple 始終對全域性變數應用相同的評估規則。它會完全評估所有全域性名稱,除非 (*) 此類變數的 (*) 值是表格或過程,在這種情況下,Maple 會在賦值鏈中的最後一個名稱處停止評估。此評估規則稱為最後名稱評估。
(*) 全部評估 (*)
完全評估規則的主要例外情況是特殊資料結構(如表格、矩陣和過程)以及過程內部區域性變數的行為。
簡而言之,將表示式括在反引號中會延遲對該表示式進行評估,使其在 Maple 解析器中迴圈一次。
引用表示式會延遲評估,但不會阻止自動簡化和算術運算。
連線通常遵循完全評估規則,但最左側的符號不會被評估。
Maple 中布林表示式的評估使用三值邏輯。
在 Maple 中,記憶體中每個物件的例項只有一個。
在內部,Maple 將每個物件分解成邏輯子物件,然後再次分解成更小的子物件,直到到達基本元素。
Maple 中的每個表示式都在內部由一個表示式樹表示,其中每個節點都是一種特定資料型別。
Maple 中的每個結構都由各個部分或運算元組成,這些部分或運算元透過各種運算子串在一起。
表示式的結構可以模擬成一棵樹。這些樹模型也被稱為“有向無環圖”或 DAG。
Maple 的整體效能部分得益於使用基於表格的演算法來執行關鍵功能。表格在 Maple 核心中用於評估和簡化,以及不太重要的功能。為了簡化,Maple 在整個會話中保留每個表示式或子表示式的單個副本。
迄今為止,Maple 核心維護的最重要的表格是簡化表格。此表格的主要目的是確保簡化的表示式在記憶體中具有唯一的例項。每個輸入到 Maple 或內部生成的表示式都會與簡化表格進行比較,如果找到,則會丟棄新表示式並使用舊錶達式。
每個表示式都使用其簽名作為鍵輸入到簡化表格中。表示式的簽名本身就是一個雜湊函式,它具有一個非常重要的屬性:等效表示式的簽名相等。如果兩個表示式不同,那麼它們在簡化基本級別上不可能相等。
如果找到簽名,則會執行完整的比較以驗證它是否為相同的表示式。
此外,由於在垃圾回收期間保留了活動物件的相對順序,這意味著物件序列可以透過機器地址進行排序。
可以使用快速載入的內部格式將 Maple 物件儲存在順序檔案中。
陣列和表格使用 Maple 的內部雜湊表實現。因此,稀疏陣列與密集陣列一樣高效。
Maple 中的包是與相關函式的集合,這些函式儲存在 Maple 庫中。
包實際上是一個函式表格,表格查詢語法直接呼叫包中的過程。
包只是一個表格,其中條目是過程,索引是過程名稱的“簡寫”。
Maple 中的包的概念允許使用者使用一個 Maple 命令(即 with 命令)定義一整套新函式。
Maple 包載入速度非常快,因為實際上,載入包只需要定義庫中新函式的位置。沒有載入任何程式碼,但包的每個成員函式都成為 readlib 定義的。(更新)
要構建一個 Maple 包,請從模組開始,使用選項包
modu:=module();
option package; ........... ........... .............. end module;
type(modu, package);
true