🚧 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.
year
Angka tahun.month
Angka bulan, Januari = 1.day
Angka tanggal dalam bulan.hour
Angka jam dalam hari dimulai dari 0.minute
Angka menit dalam jam dimulai dari 0.second
Angka detik dalam menit dimulai dari 0.
time.Time
nilai 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.
variableName
Nama 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.Time
nilai 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
text
Teks 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
.
i
variabel yang akan diperiksa.
true
Jika argumen berisinil
atau memiliki nilaiptr
yang tidak valid.false
Jika argumen bukannil
atau memiliki nilaiptr
yang 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.
i
argumen yang akan diperiksa.
true
Jika argumen berstatus Zero.false
Jika 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.
ruleName
Nama 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.
time
Variabeltime.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.
time
The 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.
time
The 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.
time
The 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.
time
The 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.
time
The 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.
time
The time variablebefore
Another time variable
- True if the
before
time value is before thetime
value. - False if the
before
time value is not before thetime
value.
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.
time
The time variableafter
Another time variable
- True if the
after
time value is after thetime
value. - False if the
after
time value is not after thetime
value.
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
.
time
The time variablelayout
String 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.
string
The string to compare to
< 0
if receiver is less than the argument0
if receiver is equal to the argument> 0
if 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.
string
The substring to check within the receiver
true
if the argument string is contained within the receiver.false
if 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.
string
The 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.
string
The expected prefix.
true
if the receiver has the argument as its prefix.false
if 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.
string
The expected suffix.
true
if the receiver has the argument as its suffix.false
if 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.
string
The 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.
string
The 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.
int64
the repeat count
- A new string containing
n
occurrences 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
.
old
the substring you wish to have replaced.new
the string you wish to replace all occurrences ofold
.
- A string where all instances of
old
in 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.
string
the 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
regexPattern
matches the string s - False if the
regexPattern
doesn'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.
val
value 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
int64
type and a real asfloat64
, thus always consider to define your function arguments and returns from the typesint64
andfloat64
when you work with numbers.