1 var EvaluationRule = {
  2 	RULE_1:function(){
  3 		var desc = "All Range Variables Should be the Same Variables in Data";
  4 		var rule = {
  5 			execute:function(programs){
  6 				new GrammerRule.UTIL().validateClauseFactVariableCount(programs);
  7 			},
  8 		
  9 			desc:function(){
 10 				return desc;
 11 			}
 12 		};
 13 		return rule;
 14 	},
 15 	
 16 	UTIL : function(){
 17 		this.validateClauseFactVariableCount = function(programs){
 18 			var prevFact ="";
 19 			var prevVarsCount = 0;
 20 			for(var i=0;i<programs.length;i++){
 21 				var fact =  programs[i].getProgram().getFact();//CLAUSE - FACT
 22 				var varsCount = fact.getVariables().length;
 23 				if(i>0 && prevVarsCount != varsCount){
 24 					throw "Invalid Number of Variable Found. 1."+fact.toString()+" \n\tAND \n2."+prevFact.toString();
 25 				}
 26 				prevFact = fact;
 27 				prevVarsCount = varsCount;
 28 			}
 29 		};
 30 		this.validateClauseFactVariableAvailabilityInClauseBody = function(program){
 31 			var fact =  program.getFact();//CLAUSE - FACT
 32 			var body = program.getBody(); // CLAUSE - BODY
 33 			var factVariables = fact.getVariables();
 34 			var bodyOutputVariables = this.getBodyOutputVariables(body);
 35 			var factVars = new Collection.Set();
 36 			factVars.addAll(factVariables);
 37 			var opVars = new Collection.Set();
 38 			opVars.addAll(bodyOutputVariables);
 39 			console.log('Expected Variables :'+factVariables+' \n Available Variables :'+bodyOutputVariables);
 40 			if(!opVars.containsAll(factVariables))
 41 				throw factVars.minus(opVars).getElements()+" Variables are missing in Clause \n"+program.toString();
 42 		};
 43 		this.validateConstrEqVariableNotAvailableInRHS = function(program){
 44 			var body = program.getBody(); // CLAUSE - BODY
 45 			for(var i=0; i < body.length; i++){
 46 				if(body[i].type() == ObjectType.OPER_EQUAL){
 47 					var lhsVariable = body[i].variable();
 48 					var constrOpVariables = new Collection.Set();
 49 					var rhsVariables = expressionTreeHelper.getConstrOpVariables(body[i].getRhs(), constrOpVariables);
 50 					if(rhsVariables.contains(lhsVariable))
 51 						throw body[i]+" LHS Variable is Reffered in RHS, Which cause Ambiguity in Expression \n";
 52 				}
 53 			}
 54 		};
 55 
 56 		this.binRelVariableShouldAvailableInFactVariablesOrConstrEqLhs = function(program){
 57 			var binRelVariables = new Collection.Set();
 58 			var bodyOutPutVariables = this.getBodyOutputVariables(program.getBody());
 59 			var bodyParts = expressionTreeHelper.getProgramBodyParts(program);
 60 			var binRelList = bodyParts.get(ObjectType.BIN_REL_LIST);
 61 			for(var i=0;i< binRelList.size(); i++){
 62 				binRelVariables = expressionTreeHelper.getBinRelVariables(binRelList.get(i), binRelVariables);
 63 			}
 64 			var bodyOutPutVariableSet = new Collection.Set();
 65 			bodyOutPutVariableSet.addAll(bodyOutPutVariables);
 66 			if(!bodyOutPutVariableSet.containsAll(binRelVariables.getElements()))
 67 				throw binRelVariables.minus(bodyOutPutVariableSet).getElements()+" Variable Not Found.";
 68 		};
 69 		/**
 70 		*	Returns teh Collection Set of the entire variable projected from FACT-RANGE and Constr-EQ
 71 		*/
 72 		this.getBodyOutputVariables = function(body){
 73 			var bodyOutputVariables = new Collection.Set();
 74 			for(var i=0;i<body.length;i++){
 75 				if(body[i].type() == ObjectType.FACT){
 76 					var fact = body[i];
 77 					bodyOutputVariables.addAll(fact.getVariables()); // Fact (variables)
 78 				}else if(body[i].type() == ObjectType.OPER_EQUAL){	// BODY - CONSTR - EQUAL
 79 					var constrEq = body[i];
 80 					bodyOutputVariables.add(constrEq.variable()); // ConstrEq LHS Variable.
 81 				}
 82 			}
 83 			return bodyOutputVariables.getElements();
 84 		};
 85 		/**
 86 		*	Method to Validate teh Fact Variable Cannot be Modified, Because it is used as a Range Variable
 87 		*/
 88 		this.factVariableShouldNotBeTheLhsOfConstrEqual = function(program){
 89 			var bodyParts = expressionTreeHelper.getProgramBodyParts(program);
 90 			var factList = bodyParts.get(ObjectType.FACT_LIST);
 91 			var constrEqList = bodyParts.get(ObjectType.CONSTR_EQ_LIST);
 92 			var factVariables = new Collection.Set();
 93 			for(var i=0;i< factList.size(); i++){
 94 				factVariables.addAll(factList.get(i).getVariables());
 95 			}
 96 			for(var i=0;i< constrEqList.size(); i++){
 97 				if(factVariables.contains(constrEqList.get(i).variable()))
 98 					throw constrEqList.get(i).variable()+" Variable Cannot be Modified, Because it is used as a Range Variable in "+factList.getElements().join(' or ');
 99 			}
100 		};
101 	}
102 };