Wednesday, May 14, 2014

RBS Drools (PART I, BASICS)

Rule-based systems - წესებზე/ბრძანებებზე დაფუძნებული სისტემა–  ძირითადად ისეთი ამოცანების გადაჭრაში გამოიყენება სადაც  ხელოვნური ინტელექტია საჭირო ან მძლავრი გამოთვლებია განსახორციელებელი. მაგალითად:  მგზავრობა მაქსიმალურად ბევრ ქალაქში ისე რომ მაქსიმალურად ცოტა თანხა დავხარჯოთ, ჭადრაკი ან თუნდაც სუდოკუ...

RBS–სათვის ბევრი პროექტები არის შექმნილი, ერთერთი არის Jboss Drools. ეს გახლავთ openSource პროექტი, რომელსაც სხვადასხვა შვილობილი (sub) პროექტები გააჩნია – Drools Expert, Drools Fusion, Drools Guvnor, Drools Planner და ასე შემდეგ.

გამახსენდა კიდევ Scala, ან IBM –ს აქვს Jrules პროექტი. Jrules ფასიანია, თუ ფული არ გვაქვს, უბრალოდ უნდა დავკმაყოფილდეთ იმით რაც გვაქვს. ამჯერად ამ სტატიაში Drools ზე ვისაუბრებთ.

სინტაქსი


 
rule "HelloPersons" 
  when 
       Person( firstName == "mariam" ) 
  then 
     // შესრულება
end  

მარტივი სინტაქსია. თუ სახელი ექვივალენტურია მარიამის, მაშინ
then ში გადავდივართ. კომპილერი ჭკვიანია და იცის რომ == იგივეა რაც String.equals

Person კლასის სხვა ველების შემოწმებაც შეგვიძლია და ასეთი სინტაქსი გვექნება:

 
rule "CheckPerson" 
when
    p: Person(age >= 18, country == "Georgia", nick: nickName)
then
    System.out.println( "Hello Mariam" );
end


ამ შემთხვევში p  არის reference variable.  აქვე პერსონის ობიექტიდან nickName ველი ამოვიღე და nick ცვლადში ჩავწერე (რათქმაუნდა  სქოუფი შეზღუდული აქ ამ ცვლადს).


პროგრამის გასაშვებად 2 გზა გვაქვს. პირველი ესაა ფლაგინის დაყენება IDE ში.

ვერსიები შეგიძლიათ აქედან ამოირჩიოთ:
 
http://download.jboss.org/drools/release/

თუმცა მე ყოველთვის ბოლო განახლებულს ვიღებ, ანუ შეგიძლიათ დააინსტალიროთ ეკლიფსში შემდეგი ლინკიდან :
 
http://download.jboss.org/drools/release/latest/org.drools.updatesite/ 


მეორე გზაა მავენის (ანუ იგივე მავნე) დეფენდენსებში დავამატოთ:

 
<dependency> 
        <groupId>org.drools</groupId> 
            <artifactId>drools-compiler</artifactId>
            <version> [ვერსია]</version> 
        </dependency> 
<dependency> 



rule ბის დასაწერად შექმენით სახელი.drl ფაილი რესურსებში. გასაშვებად კი Drools და jBPM ის მიერ შემოთავაზებული KIE API გამოგვადგება.


KieServices ks = KieServices.Factory.get(); 
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("ksession-rules"); 
 
Person p= new Person();

...     

kSession.insert(p); 
kSession.fireAllRules(); 


განვიხილოთ  ცოტა დახვეწილი მაგალითი. მაგალითად, ფიბანაჩის მიმდევრობაზე:

ჩვენ ვიცით რომ
 F(n)=F(n-1) + F(n+2)
ამასთან
 F(1) =1, და F(2)=1;



 public static class Fibonacci {

  private int sequence;
  private long value;

  public Fibonacci(int sequence) {
   this.setSequence(sequence);
   this.setValue(-1);
  }
   //... 
 } 


თავიდან  -1 მნიშვნელობები მივანიჭოთ  (–1 ით ავღნიშნოთ   ჯერ გამოუთვლელი მნიშვნელობები  )

rule "ფიბანაჩის ობიექტების შექმნა"
    when
        f : Fibonacci ( value == -1 )
        not ( Fibonacci ( sequence == 1 ) )   
    then
        insert( new Fibonacci( f.sequence - 1 ) );
        System.out.println( "recurse for " + f.sequence );
end



when –> თუ  Fibonacci ობიექტში მნიშვნელობა არის -1 (ჩვენ შექმნისას –1 მივანიჭეთ, შესაბამისად არის), მაშინ –> შევქმნათ ახალი ობიექტი , ერთით ნაკლები მიმდევრობის ნომრით.  


 rule "F(1) , F(2) ის ინიციალიზება"
    when
        f : Fibonacci(  sequence==1 || ==2, value == -1  ) 
    then
            modify ( f ){
         value = 1
     };
        System.out.println( f.sequence + " და " + f.value ); 
end



ყველა შემთხვევაში ვიცით რომ 1 –ს უდრის F(1) , F(2). ამიტომ: როცა  sequence==1 ან  sequence==2 , მაშინ გადავაკეთოთ მნიშვნელობები 1 ით. ამასთან value == -1 პირობაც დავამატოთ, თორემ ჩავიციკლებით.


და ბოლოს გამოვთვალოთ:

rule "გამოთვლა"
    when
        f1 : Fibonacci( s1 : sequence, value != -1) 
        f2 : Fibonacci( s2: sequence == (s1+1), value != -1 )
        f3 : Fibonacci( s3 : sequence == (f1.sequence+2 ), value == -1 )             
    then   
        modify ( f3 ) {
          value = f1.value + f2.value
         };
        System.out.println( s3 + " == " + f3.value ); 
end 



შედეგი
1 = 1
2 = 1
3 == 2
4 == 3
5 == 5
6 == 8
7 == 13
8 == 21
9 == 34
10 == 55
11 == 89
12 == 144
13 == 233
14 == 377
15 == 610
16 == 987
17 == 1597
18 == 2584
19 == 4181
20 == 6765
21 == 10946
22 == 17711
23 == 28657
24 == 46368
25 == 75025
26 == 121393
27 == 196418
28 == 317811
29 == 514229
30 == 832040
31 == 1346269
32 == 2178309
33 == 3524578
34 == 5702887
35 == 9227465
36 == 14930352
37 == 24157817
38 == 39088169
39 == 63245986
40 == 102334155
41 == 165580141
42 == 267914296
43 == 433494437
44 == 701408733
45 == 1134903170
46 == 1836311903
47 == 2971215073
48 == 4807526976
49 == 7778742049
50 == 12586269025
51 == 20365011074
52 == 32951280099
53 == 53316291173
54 == 86267571272
55 == 139583862445
56 == 225851433717
57 == 365435296162
58 == 591286729879
59 == 956722026041
60 == 1548008755920
61 == 2504730781961
62 == 4052739537881
63 == 6557470319842
64 == 10610209857723
65 == 17167680177565
66 == 27777890035288
67 == 44945570212853
68 == 72723460248141
69 == 117669030460994
70 == 190392490709135
71 == 308061521170129
72 == 498454011879264
73 == 806515533049393
74 == 1304969544928657
75 == 2111485077978050
76 == 3416454622906707
77 == 5527939700884757
78 == 8944394323791464
79 == 14472334024676221
80 == 23416728348467685
81 == 37889062373143906
82 == 61305790721611591
83 == 99194853094755497
84 == 160500643816367088
85 == 259695496911122585
86 == 420196140727489673
87 == 679891637638612258
88 == 1100087778366101931
89 == 1779979416004714189
90 == 2880067194370816120
91 == 4660046610375530309
92 == 7540113804746346429 
...
...
...