🚧 THIS PAGE IS BEING TRANSLATED 🚧
👷 Contributors are invited. Please read CONTRIBUTING and CONTRIBUTING TRANSLATION guidelines.
🖖 Please remove this note once you're done translating.
Tentang Grule | Tutorial | Rule Engine | GRL | GRL JSON | Algoritma RETE | Fungsi-fungsi | FAQ | Benchmark
Fungsi-fungsi built-in semuanya dapat ditemukan di file ast/BuildInFunctions.go. Saat ini, ia berisi :
MakeTime akan membuat time.Time dengan locale yang lokal.
yearAngka tahun.monthAngka bulan, Januari = 1.dayAngka tanggal dalam bulan.hourAngka jam dalam hari dimulai dari 0.minuteAngka menit dalam jam dimulai dari 0.secondAngka detik dalam menit dimulai dari 0.
time.Timenilai yang merepresentasikan waktu dimana menggunakan zona waktu lokal.
rule SetExpire "Set the expire date for Fact created before 2020" {
when
Fact.CreateTime < MakeTime(2020,1,1,0,0,0)
then
Fact.ExpireTime = MakeTime(2021,1,1,0,0,0);
}
Changed akan membuang nilai pada nama variabel yang ter-rekam dalam Working Memory menjadi hilang, sehingga nilai tersebut akan diambil lagi dari konteks data.
variableNameNama variabel yang mana nilai yang tercatat dalam working memory akan dibuang.
rule SetExpire "Set new expire date" {
when
IsZero(Fact.ExpireTime)
then
Fact.CalculateExpire(); // this function will internally change the ExpireTime variable
Changed("Fact.ExpireTime")
}
Now fungsi akan membuat nilai time.Time dengan nilai waktu saat fungsi ini dipanggil.
time.Timenilai berisi waktu sekarang.
rule ResetTime "Reset the lastUpdate time" {
when
Fact.LastUpdate < Now()
then
Fact.LastUpdate = Now();
}
Log Akan mengeluarkan sebuah log dengan tingkat "Debug" dari dalam GRL
textTeks yang akan dikeluarkan dalam log
rule SomeRule "Log candidate name if he is bellow 17 years old" {
when
Candidate.Age < 17
then
Log("Under aged : " + Candidate.Name);
}
IsNil melakukan pemeriksaan apakah nilai dalam argumen adalah nil.
ivariabel yang akan diperiksa.
trueJika argumen berisinilatau memiliki nilaiptryang tidak valid.falseJika argumen bukannilatau memiliki nilaiptryang valid.
rule CheckEducation "Check candidate's education fact" {
when
IsNil(Candidate.Education) == false &&
Candidate.Education.Grade == "PHD"
then
Candidate.Onboard = true;
}
IsZero akan memeriksa nilai argumen apakah berstatus Zero. Zero berarti
argumen tersebut baru saja dibuat dan belum diberi nilai apapun oleh program (menggunakan nilai default)
Ini biasanya berlaku pada beberapa tipe variabel seperti string, int64, uint64, bool, time.Time, etc.
iargumen yang akan diperiksa.
trueJika argumen berstatus Zero.falseJika argumen tidak berstatus Zero.
rule CheckStartTime "Check device's starting time." {
when
IsZero(Device.StartTime) == true
then
Device.StartTime = Now();
}
Retract akan menarik rule yang disebutkan dari evaluasi di siklus berikutnya.
Jika sebuah rule ditarik, maka skop when nya tidak akan dievaluasi. Saat rule engine ini dijalankan kembail
dari awal, maka semua rule yang ditarik akan dikembalikan seperti sediakala.
ruleNameNama rule yang akan ditarik.
rule CheckStartTime "Check device's starting time." salience 1000 {
when
IsZero(Device.StartTime) == true
then
Device.StartTime = Now();
Retract("CheckStartTime");
}
GetTimeYear Akan mengambil nilai tahun dari argumen.
timeVariabeltime.Time
- Nilai tahun
rule StartNewYearProcess "Check if its a new year to restart new FinancialYear." salience 1000 {
when
GetTimeYear(Now()) != GL.FinancialYear
then
GL.CloseYear(GL.FinancialYear)
}
GetTimeMonth Akan mengambil nilai bulan dari argumen.
timeThe time variable
- Month value of the time. 1 = January.
rule StartNewYearProcess "Check if its a new year to restart new FinancialYear." salience 1000 {
when
isZero(Process.Month)
then
Process.Month = GetTimeMonth(Process.Month);
}
GetTimeDay Akan mengambil nilai tanggal dari argumen.
timeThe time variable
- Day of month value of the time.
rule GreetEveryDay "Log a greeting every day." salience 1000 {
when
Greeting.Day != GetTimeDay(Now())
then
Log("Its a new Day !!!")
Retract("GreetEveryDay")
}
GetTimeHour Akan mengambil nilai jam dari argumen.
timeThe time variable
- Hour value of the time. Is between 0 to 23
rule DailyCheckBuild "Execute build every 6AM and 6PM." {
when
GetTimeHour(Now()) == 6 || GetTimeHour(Now()) == 18
then
CiCd.BuildDaily();
Retract("DailyCheckBuild");
}
GetTimeMinute Akan mengambil nilai menit dari argumen.
timeThe time variable
- Minute value of the time, between 0 to 59
rule DailyCheckBuild "Execute build every 6.30AM and 6.30PM." {
when
(GetTimeHour(Now()) == 6 || GetTimeHour(Now()) == 18) &&
GetTimeMinute(Now()) == 30
then
CiCd.BuildDaily();
Retract("DailyCheckBuild");
}
GetTimeSecond Akan mengambil nilai detik dari argumen.
timeThe time variable
- Second value of the time, between 0 to 59
rule DailyCheckBuild "Execute build every 6.30AM and 6.30PM." {
when
(GetTimeHour(Now()) == 6 || GetTimeHour(Now()) == 18) &&
GetTimeMinute(Now()) == 30 && GetTimeSecond(Now()) == 0
then
CiCd.BuildDaily();
Retract("DailyCheckBuild");
}
IsTimeBefore akan memeriksa apakah sebuah waktu pada argumen 1 itu adalah waktu sebelum nilai waktu pada argumen 2.
timeThe time variablebeforeAnother time variable
- True if the
beforetime value is before thetimevalue. - False if the
beforetime value is not before thetimevalue.
rule PromotionExpireCheck "Apply a promotion if the promotion's expired date is not due." {
when
IsTimeBefore(Now(), Promotion.ExpireDateTime)
then
Promotion.Discount = 0.10;
Retract("PromotionExpireCheck");
}
IsTimeAfter akan memeriksa apakah sebuah waktu pada argumen 1 itu adalah waktu sesudah nilai waktu pada argumen 2.
timeThe time variableafterAnother time variable
- True if the
aftertime value is after thetimevalue. - False if the
aftertime value is not after thetimevalue.
rule AdditionalTax "Apply additional tax if purchase after date specified." {
when
IsTimeAfter(Purchase.TransactionTime, TaxRegulation.StartSince)
then
Purchase.Tax = PurchaseTax + 0.01;
}
TimeFormat akan mem-format nilai waktu pada argumen sesuai dengan format yang ditentukan pada argumen layout.
timeThe time variablelayoutString variable specifying the date format layout.
For layout format, you can read this article
- String contains the formatted time
rule LogPurchaseDate "Log the purchase date." {
when
IsZero(Purchase.TransactionDate) == false
then
Log(TimeFormat(Purchase.TransactionDate, "2006-01-02T15:04:05-0700");
}
Complete will cause the engine to stop processing further rules in its
current cycle. This is useful if you want to terminate further rule evaluation
under a set condition.
rule DailyCheckBuild "Execute build at 6.30AM and 6.30PM." {
when
(GetTimeHour(Now()) == 6 || GetTimeHour(Now()) == 18) &&
GetTimeMinute(Now()) == 30 && GetTimeSecond(Now()) == 0
then
CiCd.BuildDaily();
Complete();
}All the functions bellow is a wrapper to their golang math functions. You should read Golang math page to know how to use each function.
Unlike go, you don't have to use the math. prefix
to use them in your GRL.
Use them like normal built in function.
when
Max(Fact.A, Fact.C, Fact.B) > 10
then
Fact.X = Acosh(Fact.C);- Max(vals ...float64) float64
- Min(vals ...float64) float64
- Abs(x float64) float64
- Acos(x float64) float64
- Acosh(x float64) float64
- Asin(x float64) float64
- Asinh(x float64) float64
- Atan(x float64) float64
- Atan2(y, x float64) float64
- Atanh(x float64) float64
- Cbrt(x float64) float64
- Ceil(x float64) float64
- Copysign(x, y float64) float64
- Cos(x float64) float64
- Cosh(x float64) float64
- Dim(x, y float64) float64
- Erf(x float64) float64
- Erfc(x float64) float64
- Erfcinv(x float64) float64
- Erfinv(x float64) float64
- Exp(x float64) float64
- Exp2(x float64) float64
- Expm1(x float64) float64
- Float64bits(f float64) uint64
- Float64frombits(b uint64) float64
- Floor(x float64) float64
- Gamma(x float64) float64
- Hypot(p, q float64) float64
- Ilogb(x float64) int
- IsInf(f float64, sign int64) bool
- IsNaN(f float64) (is bool)
- J0(x float64) float64
- J1(x float64) float64
- Jn(n int64, x float64) float64
- Ldexp(frac float64, exp int64) float64
- MathLog(x float64) float64
- Log10(x float64) float64
- Log1p(x float64) float64
- Log2(x float64) float64
- Logb(x float64) float64
- Mod(x, y float64) float64
- NaN() float64
- Pow(x, y float64) float64
- Pow10(n int64) float64
- Remainder(x, y float64) float64
- Round(x float64) float64
- RoundToEven(x float64) float64
- Signbit(x float64) bool
- Sin(x float64) float64
- Sinh(x float64) float64
- Sqrt(x float64) float64
- Tan(x float64) float64
- Tanh(x float64) float64
- Trunc(x float64) float64
The following functions can be called from within GRL as long as the receiver value type is correct.
Len will return string's length.
- The length of string's receiver
rule DoSomething "Do something when string length is sufficient" {
when
Fact.Name.Len() > "ATextConstant".Len()
then
Fact.DoSomething();
}Compare will compare the receiver string to the argument.
stringThe string to compare to
< 0if receiver is less than the argument0if receiver is equal to the argument> 0if receiver is greater thant the argument
rule CompareString "Do something when Fact.Text is greater than A" {
when
Fact.Text.Compare("A") > 0
then
Fact.DoSomething();
}Contains will check if its argument is contained within the receiver.
stringThe substring to check within the receiver
trueif the argument string is contained within the receiver.falseif the argument string is not contained within the receiver.
rule ContainString "Do something when Fact.Text is contains XXX" {
when
Fact.Text.Contains("XXX")
then
Fact.DoSomething();
}Count will count the number of occurences of argument in receiver string.
stringThe substring to count within the receiver
- number of occurences of the argument in the receiver.
rule CountString "Do something when Fact.Text contains 3 occurrences of 'ABC'" {
when
Fact.Text.Count("ABC") == 3
then
Fact.DoSomething();
}HasPrefix will check if the receiver string has a specific prefix.
stringThe expected prefix.
trueif the receiver has the argument as its prefix.falseif the receiver does not have the argument as its prefix.
rule IsPrefixed "Do something when Fact.Text started with PREF" {
when
Fact.Text.HasPrefix("PREF")
then
Fact.DoSomething();
}HasSuffix will check if the receiver string has a specific suffix.
stringThe expected suffix.
trueif the receiver has the argument as its suffix.falseif the receiver does not have the argument as its suffix.
rule IsSuffixed "Do something when Fact.Text ends with SUFF" {
when
Fact.Text.HasSuffix("SUFF")
then
Fact.DoSomething();
}Index will return the index of the first occurrence of the argument in the receiver string.
stringThe substring to search for.
- The index value of the first occurrence of the argument.
rule IndexCheck "Do something when Fact.Text ABC occurs as specified" {
when
Fact.Text.Index("ABC") == "abABCabABC".Index("ABC")
then
Fact.DoSomething();
}LastIndex will return the index of last occurrence of the argument in the receiver string.
stringThe substring to search for.
- The index of the last occurrence of the argument.
rule LastIndexCheck "Do something when Fact.Text ABC occurs in the last position as specified" {
when
Fact.Text.LastIndex("ABC") == "abABCabABC".LastIndex("ABC")
then
Fact.DoSomething();
}Repeat will return a string containing n occurrences of the receiver string.
int64the repeat count
- A new string containing
noccurrences of the receiver.
rule StringRepeat "Do something when Fact.Text contains ABCABCABC" {
when
Fact.Text == "ABC".Repeat(3)
then
Fact.DoSomething();
}Replace will return a string with all occurrences of old replaced with new.
oldthe substring you wish to have replaced.newthe string you wish to replace all occurrences ofold.
- A string where all instances of
oldin the receiver have been replaced withnew.
rule ReplaceString "Do something when Fact.Text contains replaced string" {
when
Fact.Text == "ABC123ABC".Replace("123","ABC")
then
Fact.DoSomething();
}Split will return a string slice whose elements are determined after
splitting the receiver by the string token argument. The token will not be
present in the resulting slice elements.
stringthe token you wish to use to split the receiver.
- The string slice containing parts of the original string as split by the token.
rule SplitString "Do something when Fact.Text is prefixed by 'ABC,'" {
when
Fact.Text.Split(",")[0] == "ABC"
then
Fact.DoSomething();
}ToLower will return a string whose contents are all lower case instances of
characters in the receiver.
- A new string that is a lower-cased version of the receiver.
rule LowerText "Do something when Fact.Text is equal to 'abc'" {
when
Fact.Text.ToLower() == "Abc".ToLower()
then
Fact.DoSomething();
}ToUpper will return a string whose contents are all upper case instances of
characters in the receiver.
- A new string that is an upper-cased version of the receiver.
rule UpperText "Do something when Fact.Text is equal to 'ABC'" {
when
Fact.Text.ToUpper() == "Abc".ToUpper()
then
Fact.DoSomething();
}Trim will return a string where the whitespace on either end of the string has been removed.
- A string with the whitespace removed from the beginning and end.
rule TrimText "Do something when Fact.Text is 'ABC'" {
when
Fact.Text == " Abc ".Trim().ToUpper()
then
Fact.DoSomething();
}MatchString MatchString reports whether the string s contains any match of the regular expression pattern. Similar to golang MatchString
- True if the
regexPatternmatches the string s - False if the
regexPatterndoesn't match the string s
rule MatchStringText "Return true when regex pattern matches the string" {
when
Fact.Text.MatchString("B([a-z]+)ck")
then
Fact.DoSomething();
}Len will return the length of the array/slice.
- The length of array/slice.
rule DoSomething "Do something when array length is sufficient" {
when
Fact.ChildrenArray.Len() > 2
then
Fact.DoSomething();
}Append will append val onto the end of the receiver array.
valvalue to have appended.
rule DoSomething "Add a new child when the array has less than 2 children" {
when
Fact.ChildrenArray.Len() < 2
then
Fact.ChildrenArray.Append(Fact.NewChild());
}Len will return map's length.
- The length of map receiver.
rule DoSomething "Do something when map length is sufficient" {
when
Fact.ChildrenMap.Len() > 2
then
Fact.DoSomething();
}Semua fungsi yang mana bisa dijalankan dari DataContext bisa dijalankan dari dalam skrip rule,
baik di dalam skop "When" atau "Then".
Karenanya, anda dapat membuat sebuah fungsi dan menjadikan fungsi ini merupakan milik (method) dari data, maka fungsi/method itu bisa dijalankan dari dalam GRL.
Diasumsikan anda memiliki sebuah struct dengan beberapa fungsi.
type MyPoGo struct {
}
func (p *MyPoGo) GetStringLength(sarg string) int {
return len(sarg)
}
func (p *MyPoGo) AppendString(aString, subString string) string {
return sprintf("%s%s", aString, subString)
}Dan struct tersebut ditambahkan kedalam konteks data
dctx := grule.context.NewDataContext()
dctx.Add("Pogo", &MyPoGo{})Anda dapat menjalan fungsi-fungsi tadi dalam rule
when
Pogo.GetStringLength(some.variable) < 100
then
some.variable = Pogo.AppendString(some.variable, "Groooling");Argumen-argumen Variadic dapat dipergunakan di dalam fungsi.
func (p *MyPoGo) GetLongestString(strs... string) string {
var longestStr string
for _, s := range strs {
if len(s) > len(longestStr) {
longestStr = s
}
}
return longestStr
}This function can then be called from within a rule with zero or more values supplied for the variadic argument
when
Pogo.GetStringLength(some.variable) < 100
then
some.longest = Pogo.GetLongestString(some.stringA, some.stringB, some.stringC);Since it is possible to provide zero values to satisfy a variadic argument, they can also be used to simulate optional parameters.
func (p *MyPoGo) AddTax(cost int64, optionalTaxRate... float64) int64 {
var taxRate float64 = 0.2
if len(optionalTaxRate) > 0 {
taxRate = optionalTaxRate[0]
}
return cost * (1+taxRate)
}when
Pogo.IsTaxApplied() == false
then
some.cost = Pogo.AddTax(come.cost);
//or
when
Pogo.IsTaxApplied() == false
then
some.cost = Pogo.AddTax(come.cost, 0.15);When you make your own function to be called from the rule engine, you need to know the following rules.
- The function must be visible. The convention for public functions should start with a capital letter. Private functions cannot be executed.
- The function must only return 1 type. Returning multiple variables from a function is not supported, the rule execution will fail if there are multiple return variables.
- The way number literals are treated in Grule's DRL is such that a decimal will always be taken as an
int64type and a real asfloat64, thus always consider to define your function arguments and returns from the typesint64andfloat64when you work with numbers.