EMMA Coverage Report (generated Tue Aug 23 05:57:12 CDT 2011)
[all classes][felix.compiler]

COVERAGE SUMMARY FOR SOURCE FILE [StaticAnalyzer.java]

nameclass, %method, %block, %line, %
StaticAnalyzer.java100% (1/1)92%  (11/12)92%  (1476/1605)89%  (282.4/319)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class StaticAnalyzer100% (1/1)92%  (11/12)92%  (1476/1605)89%  (282.4/319)
generateAllPermutations (HashSet): HashSet 0%   (0/1)0%   (0/69)0%   (0/14)
parseSpecialPredicate (): void 100% (1/1)90%  (54/60)81%  (13/16)
parseKeyConstraintRelation (): void 100% (1/1)92%  (303/328)92%  (65.9/72)
parseTransitiveRelation (): void 100% (1/1)93%  (295/316)86%  (53.5/62)
parseOtherRecursiveRelation (): void 100% (1/1)95%  (106/112)88%  (22/25)
parseReflexiveRelation (): void 100% (1/1)98%  (92/94)90%  (18/20)
StaticAnalyzer (FelixQuery, FelixCommandOptions): void 100% (1/1)100% (9/9)100% (4/4)
parse (): void 100% (1/1)100% (19/19)100% (10/10)
parseChainRecursiveRelation (): void 100% (1/1)100% (353/353)100% (48/48)
parseEmbededWeightRule (): void 100% (1/1)100% (46/46)100% (8/8)
parseNonRecursiveRelation (): void 100% (1/1)100% (63/63)100% (14/14)
parseSymmetricRelation (): void 100% (1/1)100% (136/136)100% (26/26)

1package felix.compiler;
2 
3import java.util.ArrayList;
4import java.util.HashMap;
5import java.util.HashSet;
6import java.util.Iterator;
7 
8import tuffy.mln.Literal;
9import tuffy.mln.Term;
10import tuffy.ra.Expression;
11import tuffy.ra.Function;
12import tuffy.util.ExceptionMan;
13import tuffy.util.StringMan;
14import tuffy.util.Timer;
15 
16 
17import felix.dstruct.FelixClause;
18import felix.dstruct.FelixPredicate;
19import felix.dstruct.FelixQuery;
20import felix.dstruct.FelixPredicate.FPProperty;
21import felix.dstruct.StatOperator.OPType;
22import felix.parser.FelixCommandOptions;
23 
24/**
25 * The class of static analyzer that parses a given 
26 * MLN program. It takes as input
27 * the whole MLN program, and assign properties to each 
28 * predicate. Properties include
29 * whether a predicate is SYMM, REFLEX, TRANS etc., or 
30 * whether a clause specifies a CRF
31 * chain etc.
32 * 
33 * @author Ce Zhang
34 *
35 */
36public class StaticAnalyzer {
37 
38        /**
39         * Felix Query.
40         */
41        FelixQuery fq;
42        
43        /**
44         * Command line options.
45         */
46        FelixCommandOptions options;
47        
48        /**
49         * The constructor.
50         * @param _fq
51         * @param _opt
52         */
53        public StaticAnalyzer(FelixQuery _fq, FelixCommandOptions _opt){
54                fq = _fq;
55                options = _opt;
56        }
57        
58                
59        /**
60         * Analyze the input MLN program and assign properties to each predicate.
61         */
62        public void parse(){
63                
64                //classify clauses and register them to predicates
65                //Note: the invocation order matters!
66                this.parseKeyConstraintRelation();
67                this.parseReflexiveRelation();
68                this.parseSymmetricRelation();
69                this.parseTransitiveRelation();
70                this.parseChainRecursiveRelation();
71                this.parseNonRecursiveRelation();
72                this.parseOtherRecursiveRelation();
73                this.parseSpecialPredicate();
74                this.parseEmbededWeightRule();
75                //this.parseSymmetricRelationPi2P();
76        }
77        
78        /**
79         * Parse the predicate serves as the linear-representation of COREF.
80         */
81        public void parseSpecialPredicate(){
82                
83                for(FelixPredicate p : fq.getAllPred()){
84                        String name = p.getName();
85                        if(name.endsWith("_map")){
86                        
87                                String oriName = name.replaceAll("_map$", "");
88                                
89                                if(fq.getPredByName(oriName) == null){
90                                        ExceptionMan.die("Cannot use predicate P_map without predicate P, please change to another name.");
91                                }
92                                
93                                FelixPredicate orip = fq.getPredByName(oriName);
94                                
95                                if(orip.isClosedWorld()){
96                                        ExceptionMan.die("Cannot use predicate P with predicate P as closed. Please change P to co-ref predicate, or" +
97                                                        " change the name of P_map");
98                                }
99                                
100                                if(!p.isClosedWorld()){
101                                        ExceptionMan.die("Cannot use predicate P_map with open-world setting. Plase change P_map to closed-world, or" +
102                                                        " change the name of P_map");
103                                }
104                                
105                                orip.mustbe = OPType.COREF;
106                                p.oriCorefPredicate = orip;
107                                p.isCorefMapPredicate = true;
108                                
109                                orip.corefMAPPredicate = p;
110                        
111                        }
112                }
113                
114        }
115        
116        /**
117         * Parse predicate with key constraints.
118         */
119        public void parseKeyConstraintRelation(){
120                
121                // get key constraint from predicate declaration
122                for(FelixPredicate fp : fq.getAllPred()){
123                        if(fp.hasDependentAttributes()){
124                                
125                                Object[] _labelpos = fp.getLabelAttrPositions().toArray();
126                                int[] labelpos = new int[_labelpos.length];
127                                
128                                for(int i=0;i<_labelpos.length;i++){
129                                        labelpos[i] = (Integer) _labelpos[i];
130                                }
131                                
132                                fp.registerProperty(
133                                                FelixPredicate.FPProperty.KEY_CONSTRAINT, 
134                                                null, 
135                                                labelpos);
136                        }
137                }
138                
139                // discover rules like R(a,b1), [b1!=b2], => !R(a,b2)
140                for(FelixClause fc : fq.getAllClause()){
141                        
142                        if(fc.getRegLiterals().size() != 2 || 
143                                        fc.isHardClause() == false){
144                                continue;
145                        }
146                        
147                        HashSet<FelixPredicate> processedPred = new HashSet<FelixPredicate>();
148                        
149                        for(Literal l : fc.getRegLiterals()){
150                        
151                                FelixPredicate p = fq.getPredByName(l.getPred().getName());
152                                
153                                if(processedPred.contains(p)){
154                                        continue;
155                                }
156                                
157                                processedPred.add(p);
158                                
159                                if(p.isClosedWorld()){
160                                        continue;
161                                }
162                                
163                                Literal l1 = fc.getRegLiterals().get(0);
164                                Literal l2 = fc.getRegLiterals().get(1);
165                                
166                                if(fc.getConstraints().size() != 1 || 
167                                                l1.getPred().equals(l2.getPred()) == false){
168                                        continue;
169                                }
170                                
171                                Expression e = fc.getConstraints().get(0);
172                                String var1 = "", var2 = "";
173                                
174                                boolean eqNeqFlag = false;
175                                if(e.getFunction() == Function.NOT){
176                                        e = e.getArgs().get(0);
177                                        eqNeqFlag = true;
178                                }
179                                        
180                                if (  ( eqNeqFlag == false && e.getFunction() == Function.Neq ) ||
181                                                ( eqNeqFlag == true && e.getFunction() == Function.Eq ) ){
182                                        
183                                        if(l1.getSense() == true || l2.getSense() == true){
184                                                continue;
185                                        }
186                                        
187                                        if(e.getArgs().size() != 2){
188                                                continue;
189                                        }
190                                        
191                                        Expression e1 = e.getArgs().get(0);
192                                        Expression e2 = e.getArgs().get(1);
193                                        
194                                        if(e1.getFunction() != Function.VariableBinding 
195                                                        || e2.getFunction() != Function.VariableBinding){
196                                                continue;
197                                        }
198                                        
199                                        var1 = e1.toString();
200                                        var2 = e2.toString();
201                                }else{
202                                        continue;
203                                }
204                                
205                                //check
206                                ArrayList<Term> ta = l1.getTerms();
207                                ArrayList<Term> tb = l2.getTerms();
208                                
209                                if(ta.size() != tb.size()) continue;
210                                
211                                boolean isLR = true;
212                                boolean isFirst = false;
213                                int firstI = -1;
214                                ArrayList<Integer> __labelpos = new ArrayList<Integer>();
215                                for(int i=0;i<ta.size();i++){
216                                        if(ta.get(i).toString().equals(tb.get(i).toString()) == false){
217                                        
218                                                if( (ta.get(i).toString().equals(var1) && tb.get(i).toString().equals(var2) && isFirst ==false) || 
219                                                                (tb.get(i).toString().equals(var1) && ta.get(i).toString().equals(var2) && isFirst ==false) ){
220                                                        firstI = i;
221                                                        isFirst = true;
222                                                }else{
223                                                        isLR = false;
224                                                }
225                                                
226                                                __labelpos.add(i);
227                                                
228                                        }else{
229                                                //__keypos.add(i);
230                                        }
231                                }
232                                
233                                if(firstI == -1 || isLR == false){
234                                        continue;
235                                }
236                                
237                                Object[] _labelpos = __labelpos.toArray();
238                                int[] labelpos = new int[_labelpos.length];
239                                
240                                for(int i=0;i<_labelpos.length;i++){
241                                        labelpos[i] = (Integer) _labelpos[i];
242                                }
243                                
244                                p.registerProperty(
245                                                FelixPredicate.FPProperty.KEY_CONSTRAINT, 
246                                                fc, 
247                                                labelpos);        
248                        }
249                }
250                
251        }
252        
253        /**
254         * Generates all permutations of the given terms.
255         * @param terms
256         * @return
257         */
258        public HashSet<ArrayList<String>> generateAllPermutations(HashSet<String> terms){
259                HashSet<ArrayList<String>> ret = new HashSet<ArrayList<String>>();
260                
261                if(terms.size() == 1){
262                        ArrayList<String> tmp = new ArrayList<String>();
263                        tmp.add(terms.iterator().next());
264                        ret.add(tmp);
265                        return ret;
266                }
267                
268                for(String first : terms){
269                        
270                        HashSet<String> newTerms = (HashSet<String>) terms.clone();
271                        newTerms.remove(first);
272                        
273                        HashSet<ArrayList<String>> others = this.generateAllPermutations(newTerms);
274                        for(ArrayList<String> a : others){
275                                a.add(first);
276                                ret.add(a);
277                        }
278                }
279                
280                return ret;
281        }
282        
283 
284        /**
285         * Parse predicate which is symmetric.
286         */
287        public void parseSymmetricRelation(){
288                
289                for(FelixClause fc : fq.getAllClause()){
290                        
291                        if(fc.getRegLiterals().size() != 2 || 
292                                        fc.isHardClause() == false){
293                                continue;
294                        }
295                        
296                        HashSet<FelixPredicate> processedPred = new HashSet<FelixPredicate>();
297                        
298                        for(Literal l : fc.getRegLiterals()){
299                        
300                                FelixPredicate p = fq.getPredByName(l.getPred().getName());
301                                
302                                if(processedPred.contains(p)){
303                                        continue;
304                                }
305                                
306                                processedPred.add(p);
307                                
308                                if(p.isClosedWorld()){
309                                        continue;
310                                }
311                
312                                Literal l1 = fc.getRegLiterals().get(0);
313                                Literal l2 = fc.getRegLiterals().get(1);
314                                
315                                if(!l1.getPred().equals(l2.getPred())){
316                                        continue;
317                                }
318                                
319                                if(p.arity() != 2){
320                                        continue;
321                                }
322                                
323                                if(l1.getSense() != l2.getSense()){
324                                        if(l1.getTerms().get(0).toString().equals(l2.getTerms().get(1).toString()) && 
325                                                        l1.getTerms().get(1).toString().equals(l2.getTerms().get(0).toString()) && 
326                                                        !l1.getTerms().get(1).toString().equals(l1.getTerms().get(0).toString())){
327                                                p.registerProperty(
328                                                                FPProperty.SYMM, 
329                                                                fc);
330                                        }
331                                }
332                                
333                        }
334                }
335                
336        }
337        
338        /**
339         * Parse predicate which is reflexive.
340         */
341        public void parseReflexiveRelation(){
342                
343                for(FelixClause fc : fq.getAllClause()){
344                        
345                        if(fc.getRegLiterals().size() != 1 || 
346                                        fc.isHardClause() == false){
347                                continue;
348                        }
349                        
350                        HashSet<FelixPredicate> processedPred = new HashSet<FelixPredicate>();
351                        
352                        for(Literal l : fc.getRegLiterals()){
353                        
354                                FelixPredicate p = fq.getPredByName(l.getPred().getName());
355                                
356                                if(processedPred.contains(p)){
357                                        continue;
358                                }
359                                
360                                processedPred.add(p);
361                                
362                                if(p.isClosedWorld()){
363                                        continue;
364                                }
365                                
366                                if(l.getTerms().size() == 2 && 
367                                                (l.getSense() == true)){
368                                        if(l.getTerms().get(0).var() != null && 
369                                                        l.getTerms().get(0).var().equals(l.getTerms().get(1).var())){
370                                                p.registerProperty(
371                                                                FPProperty.REFLEX, 
372                                                                fc);
373                                        }
374                                }
375 
376                        }
377                }
378        }
379        
380        /**
381         * Parse predicate which is transitive.
382         */
383        public void parseTransitiveRelation(){
384                
385                for(FelixClause fc : fq.getAllClause()){
386                        
387                        if(fc.getRegLiterals().size() != 3 || 
388                                        fc.isHardClause() == false){
389                                continue;
390                        }
391                        
392                        HashSet<FelixPredicate> processedPred = new HashSet<FelixPredicate>();
393                        
394                        for(Literal l : fc.getRegLiterals()){
395                        
396                                FelixPredicate p = fq.getPredByName(l.getPred().getName());
397                                
398                                if(processedPred.contains(p)){
399                                        continue;
400                                }
401                                
402                                processedPred.add(p);
403                                
404                                if(p.arity() != 2){
405                                        continue;
406                                }
407                                
408                                if(p.isClosedWorld()){
409                                        continue;
410                                }                
411                                
412                                if(fc.getRegLiterals().size() == 3){
413                                        
414                                        ArrayList<Literal> ls = new ArrayList<Literal>();
415                                        ls.add(fc.getRegLiterals().get(0));
416                                        ls.add(fc.getRegLiterals().get(1));
417                                        ls.add(fc.getRegLiterals().get(2));
418                                        
419                                        if(!ls.get(0).getPred().equals(ls.get(1).getPred()) ||
420                                                        !ls.get(2).getPred().equals(ls.get(1).getPred()) ||
421                                                        !ls.get(0).getPred().equals(ls.get(2).getPred())){
422                                                continue;
423                                        }
424                                
425                                        int head = -1;
426                                        int[] aa = new int[2];
427                                        int ct = 0;
428                                        for(int i=0;i<3;i++){
429                                                if(ls.get(i).getSense() == true){
430                                                        if(head != -1){
431                                                                head = -1;
432                                                                break;
433                                                        }
434                                                        head = i;
435                                                }else{
436                                                        if(ct < 2){
437                                                                aa[ct++] = i; 
438                                                        }
439                                                }
440                                        }
441                                        
442                                        if(head == -1){
443                                                continue;
444                                        }
445                                        
446                                        Literal l1 = ls.get(aa[0]);
447                                        Literal l2 = ls.get(aa[1]);
448                                        Literal h = ls.get(head);
449                                        
450                                        String common = "";
451                                        String o1 = "";
452                                        String o2 = "";
453                                        for(int i=0;i<2;i++){
454                                                for(int j=0;j<2;j++){
455                                                        if(l1.getTerms().get(i).toString().equals(l2.getTerms().get(j).toString())){
456                                                                common = l1.getTerms().get(i).toString();
457                                                                o1 = l1.getTerms().get((i+1)%2).toString();
458                                                                o2 = l2.getTerms().get((j+1)%2).toString();
459                                                                break;
460                                                        }
461                                                }
462                                                if(common.equals("") == false){
463                                                        break;
464                                                }
465                                        }
466                                        
467                                        if(common.equals("")){
468                                                continue;
469                                        }
470                                        
471                                        if( h.getTerms().get(0).toString().equals(o1) && h.getTerms().get(1).toString().equals(o2) ){
472                                                p.registerProperty(
473                                                                FPProperty.TRANS,
474                                                                fc);
475                                        }
476                                        
477                                        if( h.getTerms().get(1).toString().equals(o1) && h.getTerms().get(0).toString().equals(o2) ){
478                                                p.registerProperty(
479                                                                FPProperty.TRANS,
480                                                                fc);
481                                        }
482                                }
483                        }
484                }
485                
486        }
487        
488        /**
489         * Parse clause which specifies a CRF chain rule.
490         */
491        public void parseChainRecursiveRelation(){
492                
493                for(FelixClause fc : fq.getAllClause()){
494                        
495                        HashSet<FelixPredicate> processedPred = new HashSet<FelixPredicate>();
496                        
497                        for(Literal l : fc.getRegLiterals()){
498                        
499                                FelixPredicate p = fq.getPredByName(l.getPred().getName());
500                                
501                                if(processedPred.contains(p)){
502                                        continue;
503                                }
504                                
505                                processedPred.add(p);
506                                
507                                if(p.isClosedWorld()){
508                                        continue;
509                                }
510 
511                                if(fc.getLiteralsOfPredicate(l.getPred()).size() != 2){
512                                        continue;
513                                }
514                                
515                                Literal l1 = fc.getLiteralsOfPredicate(l.getPred()).get(0);
516                                Literal l2 = fc.getLiteralsOfPredicate(l.getPred()).get(1);
517                        
518                                boolean isCRFRule = true;
519                                                        
520                                int numberOfDifference = 0;
521                                for(int i=0;i<l1.getTerms().size();i++){
522                                        Term t1 = l1.getTerms().get(i);
523                                        Term t2 = l2.getTerms().get(i);
524        
525                                        if(t1.toString().equals(t2.toString())){
526                                                // if these two terms are the same, good!
527                                                continue;
528                                        }else{
529                                                // if not, we need to see whether in this rule,
530                                                // t1 and t2 is representing a chain. Here we know 
531                                                // there can be only one label-field, so, only one 
532                                                // such t1-t2 pair can exist.
533                                                
534                                                if(!p.getKeyPositions().contains(i)){
535                                                        continue;
536                                                }
537                                                
538                                                numberOfDifference ++;
539                                                                                
540                                                boolean isChain = false;
541                                                
542                                                // find in condition [t1 = t2 + 1]
543                                                //TODO: We may want to change it smarter in the future
544                                                for(Expression e : fc.getConstraints()){
545                                                        if(e.toString().equals(t1+" = (" + t2 + " + 1)") ||
546                                                                e.toString().equals(t2+" = (" + t1 + " + 1)") ||
547                                                                e.toString().equals("(" + t1 + " + 1) = " + t2) ||
548                                                                e.toString().equals("(" + t2 + " + 1) = " + t1) ||
549                                                                e.toString().equals(t1+" = (" + t2 + " - 1)") ||
550                                                                e.toString().equals(t2+" = (" + t1 + " - 1)") ||
551                                                                //TODO
552                                                                e.toString().equals("(" + t1 + " - 1) = (" + t2 + " + 0)") ||
553                                                                e.toString().equals("(" + t2 + " - 1) = (" + t1 + " + 0)") ||
554                                                                e.toString().equals("(" + t1 + " - " + t2 + ") = " + 1) ||
555                                                                e.toString().equals(1 + " = (" + t1 + " - " + t2 + ")") || 
556                                                                e.toString().equals("(" + t2 + " - " + t1 + ") = " + 1) ||
557                                                                e.toString().equals(1 + " = (" + t2 + " - " + t1 + ")")){
558                                                                        isChain = true;
559                                                        }
560                                                }
561                                                
562                                                if(!isChain){
563                                                        isCRFRule = false;
564                                                }
565                                                                                
566                                                if(numberOfDifference != 1){
567                                                        isCRFRule = false;
568                                                }
569                                        }
570                                }
571                                
572                                if(isCRFRule == true && numberOfDifference > 0){
573                                        if(p.getKeyPositions().size() != 0){
574                                                p.registerProperty(
575                                                                FPProperty.CHAIN_RECUR, 
576                                                                fc);
577                                        }
578                                }
579                                
580                        }
581                }
582                
583        }
584        
585        // rules other than special rules
586        /**
587         * Parse clause which does NOT specify 1) NON-RECURSIVE rule and 
588         * 2) Chain rule.
589         * 
590         */
591        public void parseOtherRecursiveRelation(){
592                for(FelixClause fc : fq.getAllClause()){
593                        
594                        HashSet<FelixPredicate> processedPred = new HashSet<FelixPredicate>();
595                        
596                        HashSet<FelixPredicate> appeared = new HashSet<FelixPredicate>();
597                        
598                        for(Literal l : fc.getRegLiterals()){
599                                FelixPredicate p = fq.getPredByName(l.getPred().getName());
600                                
601                                if(p.isClosedWorld()){
602                                        continue;
603                                }
604                                
605                                appeared.add(p);
606                        }
607                        
608                        
609                        
610                        
611                        for(Literal l : fc.getRegLiterals()){
612                        
613                                FelixPredicate p = fq.getPredByName(l.getPred().getName());
614                        
615                                if(p.isClosedWorld()){
616                                        continue;
617                                }
618                                
619                                if(processedPred.contains(p)){
620                                        continue;
621                                }
622                                
623                                processedPred.add(p);
624                                
625                                if(appeared.size() == 1){
626                                        if(fc.getLiteralsOfPredicate(l.getPred()).size() > 1){
627                                                p.registerProperty(
628                                                                FPProperty.OTHER_RECUR, 
629                                                                fc);
630                                        }
631                                }else{
632                                        if(fc.getLiteralsOfPredicate(l.getPred()).size() > 1){
633                                                p.registerProperty(
634                                                                FPProperty.OTHER_RECUR_WITHOTHER_OPENPRED, 
635                                                                fc);
636                                        }
637                                }
638 
639                        }
640                }
641        }
642        
643        
644        /**
645         * Parse clause which specifies non-recursive rules.
646         */
647        public void parseNonRecursiveRelation(){
648 
649                for(FelixClause fc : fq.getAllClause()){
650                        
651                        HashSet<FelixPredicate> processedPred = new HashSet<FelixPredicate>();
652                        
653                        for(Literal l : fc.getRegLiterals()){
654                        
655                                FelixPredicate p = fq.getPredByName(l.getPred().getName());
656                        
657                                if(p.isClosedWorld()){
658                                        continue;
659                                }
660                                
661                                if(processedPred.contains(p)){
662                                        continue;
663                                }
664                                
665                                processedPred.add(p);
666                                
667                                if(fc.getLiteralsOfPredicate(l.getPred()).size() == 1){
668                                        p.registerProperty(
669                                                        FPProperty.NON_RECUR, 
670                                                        fc);
671                                }
672 
673                        }
674                }
675        }
676        
677        /**
678         * Parse clause whose weights are specified by embedded weight.
679         */
680        public void parseEmbededWeightRule(){
681 
682                for(FelixClause fc : fq.getAllClause()){
683                        
684                        for(Literal l : fc.getRegLiterals()){
685                        
686                                FelixPredicate p = fq.getPredByName(l.getPred().getName());
687                        
688                                if(p.isClosedWorld()){
689                                        continue;
690                                }
691                                
692                                if(fc.hasEmbeddedWeight()){
693                                        p.registerProperty(FPProperty.EMBED_WEIGHT_RULE, fc);
694                                }
695 
696                        }
697                        
698                }
699        }
700        
701}

[all classes][felix.compiler]
EMMA 2.0.5312 EclEmma Fix 2 (C) Vladimir Roubtsov