001    /*
002    @license.text@
003     */
004    package com.hammurapi.reasoning.tutorial;
005    
006    import java.io.File;
007    import java.util.ArrayList;
008    import java.util.Collections;
009    import java.util.List;
010    import java.util.concurrent.Executor;
011    import java.util.concurrent.PriorityBlockingQueue;
012    import java.util.concurrent.ThreadPoolExecutor;
013    import java.util.concurrent.TimeUnit;
014    import java.util.concurrent.atomic.AtomicInteger;
015    
016    import com.hammurapi.config.runtime.FactoryConfig;
017    import com.hammurapi.reasoning.ExceptionHandler;
018    import com.hammurapi.reasoning.ForwardReasoningSession;
019    import com.hammurapi.reasoning.ReasoningException;
020    import com.hammurapi.reasoning.impl.ForwardReasoningSessionFactoryImpl;
021    import com.hammurapi.reasoning.tutorial.objectmodel.Child;
022    import com.hammurapi.reasoning.tutorial.objectmodel.Person;
023    import com.hammurapi.reasoning.tutorial.objectmodel.Relative;
024    import com.hammurapi.reasoning.tutorial.objectmodel.Spouse;
025    import com.hammurapi.util.CompositeContext;
026    import com.hammurapi.util.DefaultContext;
027    import com.hammurapi.util.SimpleMutableContext;
028    
029    public class Tutorial {
030    
031            /**
032             * Infers relationships.
033             * @throws ReasoningException 
034             */
035            private static void putFacts(ForwardReasoningSession<Relative> session) throws ReasoningException {
036                    
037                    Person kate = new Person("Kate", 58, false);
038                    Person victor = new Person("Victor", 63, true);
039                    session.put(new Spouse(kate, victor));
040    
041                    Person peter = new Person("Peter", 37, true);
042                    session.put(new Child(peter, kate));
043                    session.put(new Child(peter, victor));
044                    
045                    Person alison = new Person("Alison", 36, false);
046                    session.put(new Spouse(peter, alison));
047    
048                    Person lucy = new Person("Lucy", 17, false);
049                    session.put(new Child(lucy, alison));
050                    
051                    Person nancy = new Person("Nancy", 14, false);
052                    session.put(new Child(nancy, peter));
053                    
054                    Person dan = new Person("Dan", 7, true);
055                    session.put(new Child(dan, peter));
056                    session.put(new Child(dan, alison));
057                    
058                    Person audrey = new Person("Audrey", 4, false);
059                    session.put(new Child(audrey, peter));
060                    session.put(new Child(audrey, alison));         
061                    
062                    Person tanya = new Person("Tanya", 31, false);
063                    Person max = new Person("Max", 32, true);
064                    session.put(new Spouse(tanya, max));
065                    session.put(new Child(tanya, kate));
066                    session.put(new Child(tanya, victor));
067    
068                    Person vilma = new Person("Vilma", 14, false);
069                    session.put(new Child(vilma, tanya));
070                    
071                    Person george = new Person("George", 10, true);
072                    session.put(new Child(george, tanya));
073                    
074                    Person lisa = new Person("Lisa", 5, false);
075                    session.put(new Child(lisa, tanya));
076                    session.put(new Child(lisa, max));              
077            }
078    
079            /**
080             * Main method for the tutorial.
081             * @param args The first argument is rule set URI.
082             */
083            public static void main(String[] args) throws Exception {       
084                    long factoryStart = System.currentTimeMillis();
085                    System.out.println("Hammurapi rules tutorial");
086                    
087                    if (args.length!=1) {
088                            System.out.println("Usage: java <options> biz.hammurapi.rules.tutorial.Tutorial <rule set file>");
089                            System.exit(1);
090                    }
091                    
092                    FactoryConfig factoryConfig = new FactoryConfig();
093                                    
094                    final AtomicInteger commandCounter = new AtomicInteger();
095                    
096                    ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 15, 20, TimeUnit.SECONDS, new PriorityBlockingQueue<Runnable>()) {
097                            @Override
098                            public void execute(Runnable command) {
099                                    commandCounter.incrementAndGet();
100                                    super.execute(command);
101                            }
102                    };
103                    
104                    SimpleMutableContext sc = new SimpleMutableContext();
105                    sc.register(Executor.class, executor);
106                    
107                    factoryConfig.setContext(new CompositeContext(new DefaultContext(Tutorial.class.getClassLoader(), null), sc));
108                    
109                    ForwardReasoningSessionFactoryImpl<Relative> factory = new ForwardReasoningSessionFactoryImpl<Relative>(new File(args[0]), factoryConfig);          
110                    
111                    ForwardReasoningSession<Relative> session = factory.createSession(null);
112                    
113                    session.setExceptionHandler(new ExceptionHandler() {
114                            
115                            @Override
116                            public void handleException(Exception e) throws Exception {
117                                    System.out.println("Exception: "+e);                            
118                            }
119                    });
120                    
121                    System.out.println("Session created in "+(System.currentTimeMillis()-factoryStart));
122                    long start = System.currentTimeMillis();
123                    try {
124                            putFacts(session);
125                            session.executeRules();
126                            
127                            List<Relative> allFacts = new ArrayList<Relative>(session.getObjects());
128                            Collections.sort(allFacts);
129                            
130                            System.out.println("Inference time "+(System.currentTimeMillis()-start)+" for "+allFacts.size()+" objects.");
131                            System.out.println("Commands executed "+commandCounter.get());
132                            System.out.println("=== All facts ===");
133                            int factNo = 0;
134    //                      int maxDepth = 0;
135    //                      int maxCardinality = 0;
136    //                      Object maxCardinalityFact = null;
137                            Person lastSubject = null;
138                            for (Relative fact: allFacts) {                         
139                                    if (lastSubject==null || !lastSubject.equals(fact.getSubject())) {
140                                            if (lastSubject!=null) {
141                                                    System.out.println("---");
142                                            }
143                                            lastSubject = fact.getSubject();
144                                    }
145                                    System.out.println(++factNo+": "+fact);
146    //                              int dc = 0;
147    //                              for (Derivation<Object> d: session.getDerivations(fact)) {
148    //                                      System.out.println(++dc+": "+d);
149    //                                      maxDepth = Math.max(maxDepth, d.getDepth());
150    //                                      int c = d.getCardinality();
151    //                                      if (c>maxCardinality) {
152    //                                              maxCardinality = c;
153    //                                              maxCardinalityFact = fact;
154    //                                      }
155    //                              }
156    //                              System.out.println("---");
157                            }
158                            
159    //                      System.out.println("Max depth: "+maxDepth);
160    //                      System.out.println("Max cardinality: "+maxCardinality);
161    //                      
162    //                      System.out.println("~~~ Max cardinality fact: "+maxCardinalityFact);
163    //                      int dc = 0;
164    //                      for (Derivation<Object> d: session.getDerivations(maxCardinalityFact)) {
165    //                              System.out.println(++dc+": "+d);
166    //                      }
167    //                      System.out.println("---");
168                            
169                            // Exclude already known.
170                            
171                            // Derivations.
172                    } finally {
173                            session.close();
174                    }
175                    executor.shutdown();
176            }
177    
178    }