《Drools7.0.0.Final規則引擎教程》第4章 4.4 約束(Pattern的一部分)
4.4.3 約束(Pattern的一部分)
前面我們已經介紹了條件約束在Pattern中位置了,那麼什麼是條件約束呢?簡單來說就是一個返回true或者false的表示式,比如下面的5小於6,就是一個約束條件。
Person( 5 < 6 )
從本質上來講,它是JAVA表示式的一種增強版本(比如屬性訪問),同時它又有一些小的區別,比如equals方法和==的語言區別。下面我們就深入瞭解一下。
訪問JavaBean中的屬性
任何一個JavaBean中的屬性都可以訪問,不過對應的屬性要提供getter方法或isProperty方法。比如:
Person( age == 50 )
// 與上面擁有同樣的效果
Person( getAge() == 50 )
Drools使用java標準的類檢查,因此遵循java標準即可。同時,巢狀屬性也是支援的,比如:
Person( address.houseNumber == 50 )
// 與上面寫法相同
Person( getAddress().getHouseNumber() == 50 )
在使用有狀態session的情況下使用巢狀屬性需要注意屬性的值可能被其他地方修改。要麼認為它們是不可變的,當任何一個父引用被插入到working memory中。或者,如果要修改巢狀屬性值,則應將所有外部fact標記更新。在上面的例子中,當houseNumber屬性值改變時,任何一個包含Address的Person需要被標記更新。
Java表示式
在pattern的約束條件中,可以任何返回結果為布林型別的java表示式。當然,java表示式也可以和增強的表示式進行結合使用,比如屬性訪問。可以通過使用括號來更改計算優先順序,如在任一邏輯或數學表示式中。
Person( age > 100 && ( age % 10 == 0 ) )
也可以直接使用java提供的工具方法來進行操作計算:
Person( Math.round( weight / ( height * height ) ) < 25.0 )
在使用的過程中需要注意,在LHS中執行的方法只能是隻讀的,不能在執行方法過程中改變改變FACT物件的值,否則會影響規則的正確執行。
Person( incrementAndGetAge() == 10 ) //不要像這樣在比較的過程中更新Fact物件
另外,FACT物件的相關狀態除了被在working memory中進行更新操作,不應該每次呼叫時狀態會發生變化。
Person( System.currentTimeMillis() % 1000 == 0 ) // 不要這樣實現
標準Java運算子優先順序也適用,請參見下面的運算子優先順序列表。所有的操作符都有標準的Java語義,除了==和!=。它們的null安全的,就相當於java中比較兩個字串時把常量字串放前面呼叫equals方法的效果一樣。
約束條件的比較過程中是會進行強制型別轉換的,比如在資料計算中傳入字串“10”,則能成功轉換成數字10進行計算。但如果,此時傳入的值無法進行轉換,比如傳了“ten”,那麼將會丟擲異常。
逗號分隔符
逗號可以對約束條件進行分組,它的作用相當於“AND”。
// Person的年齡要超過50,並且重量 超過80 kg
Person( age > 50, weight > 80 )
雖然“&&”和“,”擁有相同的功能,但是它們有不同的優先順序。“&&”優先於“||”,“&&”和“||”又優先於“,”。但建議優先使用“,”分隔符,因為它更利於閱讀理解和引擎的優化操作。同時,逗號分隔符不能和其他操作符混合使用,比如:
Person( ( age > 50, weight > 80 ) || height > 2 ) // 會編譯錯誤
// 使用此種方法替代
Person( ( age > 50 && weight > 80 ) || height > 2 )
繫結變數
一個屬性可以繫結到一個變數:
// 2 person的age屬性值相同
Person( $firstAge : age ) // 繫結
Person( age == $firstAge ) // 約束表示式
字首$只是個通用慣例,在複雜規則中可以通過它來區分變數和屬性。為了向後相容,允許(但不推薦)混合使用約束繫結和約束表示式。
// 不建議這樣寫
Person( $age : age * 2 < 100 )
// 推薦(分離繫結和約束表示式)
Person( age * 2 < 100, $age : age )
使用操作符“==”來繫結變數,Drools會使用雜湊索引來提高執行效能。
內部類分組訪問
通常情況,我們訪問一個內部類的多個屬性時會有如下的寫法:
Person( name == "mark", address.city == "london", address.country == "uk" )
Drools提供的分組訪問可以更加方便進行使用:
Person( name == "mark", address.( city == "london", country == "uk") )
注意字首’.’是用來區分巢狀物件約束和方法呼叫所必需的。
內部強制轉換
在使用內部類的時候,往往需要將其轉換為父類,在規則中可以通過“#”來進行強制轉換:
Person( name == "mark", address#LongAddress.country == "uk" )
上面的例子將Address強制轉換為LongAddress.,這樣使得getter方法變得可用。如果無法強制轉換,表示式計算的結果為false。強制轉換也支援全路徑的寫法:
Person( name == "mark", address#org.domain.LongAddress.country == "uk" )
多次內部轉換語法:
Person( name == "mark", address#LongAddress.country#DetailedCountry.population > 10000000 )
也可以使用instanceof操作符進行判斷,判斷之後將進一步使用該屬性進行比較。
Person( name == "mark", address instanceof LongAddress, address.country == "uk" )
日期字元
規則語法中除了支援JAVA標準字元,同時也支援日期字元。Drools預設支援的日期格式為“dd-mmm-yyyy”,可以通過設定系統變數“drools.dateformat”的值來改變預設的日期格式。
Cheese( bestBefore < "27-Oct-2009" )
List和Map的訪問
訪問List:
// 和childList(0).getAge() == 18效果相同
Person( childList[0].age == 18 )
根據key訪問map:
// 和credentialMap.get("jsmith").isValid()相同
Person( credentialMap["jsmith"].valid )
&&和||
約束表示式可以通過&&和||來進行判斷比較,此處用法與標準Java相似,當組合使用時,可通過括號來劃分優先順序。
Person( age > 30 && < 40 )
Person( age ( (> 30 && < 40) ||(> 20 && < 25) ) )
Person( age > 30 && < 40 || location == "london" )
DRL特殊操作符
“< ⇐ > >=”操作符用於屬性的比較是按照預設的排序,比如日期屬性使用小於號標示可以按照日期排序,當使用在String字串的比較時,則按照字母順序進行排序。此操作符僅適用於可比較的屬性。
Person( firstName < $otherFirstName )
Person( birthDate < $otherBirthDate )
“!.”提供了一個預設空校驗的操作。當使用此操作符時,會先校驗當前物件是否為null,如果不為null再呼叫其方法或獲得其屬性進行判斷。一旦當前操作物件為null,則相當於結果為false。
Person( $streetName : address!.street )
// 上面的寫法相當於
Person( address != null, $streetName : address.street )
matches操作符可使用Java的正則表示式進行字串的匹配,通常情況下是對字串進行匹配,但也支援變數值為正確的表示式的方式。此操作符僅適用於字串屬性。如果屬性值為null,匹配的結果始終為false。
Cheese( type matches "(Buffalo)?\\S*Mozzarella" )
not matches方法與matches相同,唯一不同的是返回的結果與之相反。
Cheese( type not matches "(Buffalo)?\\S*Mozzarella" )
contains操作符判斷一個集合屬性或元素是否包含指定字串或變數值。僅適用於集合屬性。也可以用於替代String.contains()來檢查約束條件。not contains用法與之相同,結果取反。
CheeseCounter( cheeses contains "stilton" ) // 包含字串
CheeseCounter( cheeses contains $var ) // 包含變數
Cheese( name contains "tilto" )
Person( fullName contains "Jr" )
String( this contains "foo" )
memberOf用來檢查屬性值是否為集合,此集合的表示必須為變數。not memberOf使用方法相同,結果取反。
CheeseCounter( cheese memberOf $matureCheeses )
soundslike的效果與matches相似,但它用來檢查一個字串的發音是否與指定的字元十分相似(使用英語發音)。
// 匹配 "fubar" 或 "foobar"
Cheese( name soundslike 'foobar' )
str操作用來比較一個字串是否以指定字串開頭或結尾,有可以用於比較字串的長度。
Message( routingValue str[startsWith] "R1" )
Message( routingValue str[endsWith] "R2" )
Message( routingValue str[length] 17 )
in和notin用來匹配一組資料中是否含一個或多個匹配的字串,使用的方法與資料庫中in的使用方法相似。待匹配的資料可以是字串、變數。
Person( $cheese : favouriteCheese )
Cheese( type in ( "stilton", "cheddar", $cheese ) )
運算子優先順序
操作型別 | 操作符 | 備註 |
---|---|---|
(巢狀/空安全)屬性訪問 | .!. | 非標準java語義 |
List/Map訪問 | [ ] | 非標準java語義 |
約束繫結 | : | 非標準java語義 |
乘除 | */% | |
加減 | +- | |
移位 | <<>>>>> | |
關係 | <>⇐>=instanceof | |
等 | ==!= | 未使用標準java語義,某些語義相當於equals。 |
非短路AND | & | |
非短路異或 | ^ | |
非短路包含OR | | | |
邏輯與 | && | |
邏輯或 | || | |
三元運算子 | ? : | |
逗號分隔,相當於and | , | 非標準java語義 |
後語
此係列課程持續更新中,QQ群:593177274(可掃描左上側欄目二維碼),歡迎大家加入討論。點選連結關注《Drools部落格專欄》。由於Drools資料較少,教程編寫不易,每篇部落格都親身實踐編寫demo。如果對你有幫助也歡迎讚賞(微信)! 也是對原創的最大支援!
相關推薦
《Drools7.0.0.Final規則引擎教程》第1章 Drools簡介
1.1 什麼是規則引擎 規則引擎是由推理引擎發展而來,是一種嵌入在應用程式中的元件,實現了將業務決策從應用程式程式碼中分離出來,並使用預定義的語義模組編寫業務決策。接受資料輸入,解釋業務規則,並根據業務規則做出業務決策。 大多數規則引擎都支援規則的次序和規
《Drools7.0.0.Final規則引擎教程》第4章 4.6 結果條件
結果條件 在Java中,如果有重複的程式碼我們會考慮進行重構,抽取公共方法或繼承父類,以減少相同的程式碼在多處出現,達到程式碼的最優管理和不必要的麻煩。Drools同樣提供了類似的功能。下面我們以例項來逐步說明。 像下面最原始的兩條規則,有相同的業務判斷,也
《Drools7.0.0.Final規則引擎教程》第3章 3.2 KIE API解析
3.2.4 KieServices 該介面提供了很多方法,可以通過這些方法訪問KIE關於構建和執行的相關物件,比如說可以獲取KieContainer,利用KieContainer來訪問KBase和KSession等資訊;可以獲取KieRepository物件
《Drools7.0.0.Final規則引擎教程》第4章 4.4 約束(Pattern的一部分)
4.4.3 約束(Pattern的一部分) 前面我們已經介紹了條件約束在Pattern中位置了,那麼什麼是條件約束呢?簡單來說就是一個返回true或者false的表示式,比如下面的5小於6,就是一個約束條件。 Person( 5 < 6 ) 從本質上
《Drools7.0.0.Final規則引擎教程》第4章 註釋&錯誤資訊
註釋 像Java開發語言一樣,Drools檔案中也可以添加註釋。註釋部分Drools引擎是會將其忽略調的。單行註釋使用“//”,示例如下: rule "Testing Comments" when // this is a single line
《Drools7.0.0.Final規則引擎教程》之Springboot整合
本來準備按部就班的一章一章更新Drools相關教程,怎奈QQ群組(593177274)有朋友急需Springboot與Drools的整合demo,於是抽出時間寫了一個,現在拿出來分享一下。加入群組可免費下載demo,也可以在CSDN下載頻道下載:Springbo
《Drools7.0.0.Final規則引擎教程》番外例項篇——Map使用案例
背景 技術交流群中,不少朋友在問,如何在Drools規則檔案中使用Map。今天就用例項帶大家瞭解一下map的使用方法。 例項程式碼 測試部分程式碼: @Test public void testMapUsage() { KieSe
AutoCAD2012從入門到精通中文視訊教程 第19課 修剪與延伸(個人收藏)
修剪和延伸的基本技巧首先是選擇,首先要選擇修剪、延伸邊界,或稱為切割物件,也就是選擇作為修剪和延伸的基準的物件,然後就是選擇要被修剪或延伸的物件,掌握了這兩者的選擇技巧就基本掌握了修剪和延伸的操作。 CAD修剪(Trim)和延伸(Extend)的使用技巧 2
Hadoop基礎教程-第2章 Hadoop快速入門(2.2 Hadoop下載與安裝)
2.1 Hadoop下載與安裝2.1.1 官網下載可以使用迅雷或QQ旋風等多執行緒下載工具來下載,支援斷點續傳。成功下載後得到hadoop-2.7.3.tar.gz壓縮檔案,204M。請檢查壓縮包是否204M,瀏覽器下載的話可能會中斷。2.1.2 上傳至虛擬機器通過ll或ls命令可以檢視到已經上傳到虛擬機器n
Hadoop基礎教程-第1章 環境安裝配置(1.5 構建叢集)
第1章 環境安裝配置 1.5 構建叢集 1、叢集概念 根據百度的解釋: 叢集是一組相互獨立的、通過高速網路互聯的計算機,它們構成了一個組,並以單一系統的模式加以管理。一個客戶與叢集相互作用時,叢集像是一個獨立的伺服器。叢集配置是用於提高可用性和可
Node.js進階教程第七步:koa框架(koa1,koa2)-何韜-專題視訊課程
Node.js進階教程第七步:koa框架(koa1,koa2)—6512人已學習 課程介紹 koa 致力於成為一個更小、更富有表現力、更健壯的 Web 框架。Koa 應用是一個包含一系列中介軟體 generator 函式的物件。Koa提供了一個輕量優雅的函式庫,
Hadoop基礎教程-第2章 Hadoop快速入門(2.4 Hadoop單機執行)
第2章 Hadoop快速入門2.4 Hadoop單機執行緊接上一節內容,首先切換到Hadoop根目錄 或者cd /opt/hadoop-2.7.3進入Hadoop根目錄 通過pwd命令可以知道當前所在目錄[root@node1 hadoop-2.7.3]# pwd注意:本節命令都將在/opt/hadoop-2
【閱讀筆記】《C程序員 從校園到職場》第三章 程序的樣式(大括號)
突出 char s 結構體 需要 初始化 detail 處理 思維 https 參考: https://blog.csdn.net/zhouzhaoxiong1227/article/details/22820533 一、.初始化數組變量 在實際的軟件開
第六章:隨機化(續1)
限制 調試 each 範圍 實例 func 文件中 約束 hand 6.6 pre_randomize和post_randomize函數 我們在調用randomize()函數之前或者之後要立即執行一些操作。比如,在隨機化之前可能要設置類裏的一些非隨機變量(上下限、權重),或
第六章:隨機化(續2)
重要 之間 ilog -o bbbb 動態 調試 即使 不同 6.10 隨機化句柄數組 如果想要產生多個隨機對象,那麽你可能需要建立隨機句柄數組,和整數數組不同,隨機求解器不會創建對象,所以你需要在隨機化前分配所有的元素。 動態數組可以按照需要分配最大數量的元素,然後按照約
組合語言第三章暫存器(記憶體訪問)
3.1 在CPU中,用一個16位暫存器來儲存一個字,一個字兩個位元組,高8位存放高位位元組,低8位存放低位位元組,低位元組所在的記憶體單元稱為起始地址。 3.2 3.3 8086CPU中,通常用DS暫存器來存放要訪問資料的段地址(字或者位元組) 舉個例子: mov bx,1000H mov
第3章 暫存器(記憶體訪問)小結
記憶體中字的儲存 字單元,即存放一個字形資料(16位)的記憶體單元,由兩個地址連續的記憶體單元組成。高地址記憶體單元中存放字型資料的高位位元組,低地址記憶體單元中存放字型資料的低位位元組。我們將起始地址為N的字單元簡稱為N地址字單元。 DS和[address] “[...]”表示一個記憶
第三章 暫存器(記憶體訪問)相關內容總結
在本章中,我們從訪問記憶體的角度繼續學習了幾個暫存器。我們提出字單元的概念:字單元,即存放一個字型資料(16位)的記憶體單元,由兩個地址連續的記憶體單元組成。高地址記憶體單元中存放字型資料的高位位元組,低地址記憶體單元中存放字型資料的低位位元組。CPU要讀寫一個記憶體
強化學習(RLAI)讀書筆記第六章差分學習(TD-learning)
第六章:Temporal-Difference Learning TD-learning演算法是強化學習中一個獨具特色而又核心的想法,結合了蒙特卡洛演算法和動態規劃的想法。和MC一樣不需要環境模型直接從sample裡學習,也像DP一樣使用bootstrap通過別的狀態值的估計更新當前狀態值。首先
《機器學習》 周志華學習筆記第六章 支援向量機(課後習題)python 實現
一、 1.間隔與支援向量 2.對偶問題 3.核函式 xi與xj在特徵空間的內積等於他們在原始yangben空間中通過函式k(.,.)計算的結果。 核矩陣K總是半正定的。 4.軟間隔與正則化 軟間隔允許某些samples不滿足約束 鬆弛變數 5.支援