def process_query_call(self, *args): args = map(lambda arg: arg.replace('"', ''), args) args = list(args) self.print_args(args, "PROCESS_QUERY") unique_rule_name = string_to_py_type(args[0], "STRING") template_name = string_to_py_type(args[1], "STRING") field_name = string_to_py_type(args[2], "STRING") line_start = string_to_py_type(args[3], "INTEGER") col_start = string_to_py_type(args[4], "INTEGER") line_end = string_to_py_type(args[5], "INTEGER") col_end = string_to_py_type(args[6], "INTEGER") tmp_update_rule = QUERY_RULE.format( unique_rule_name, template_name, field_name, line_start, col_start, line_end, col_end ) if self.debug: print("\nQUERY RULE: " + tmp_update_rule) print("\nQUERY RULE TRANSPILATION PRINT:") transpiler = Transpiler(self.env_provider, True) transpiler.load(tmp_update_rule) self.env_provider.insert_rule(transpiler.rule.rule_name, transpiler.tranpiled_rule) return 0
def load_all_rules(): global all_rules_loaded if all_rules_loaded: message = "All rules are already loaded." return response(None, message, 0, 0, RespType.INFO) all_rules_loaded = True # Insert RULES from database cursors = mongo.db.rules.find({}) rules = list(cursors) for akashic_rule in rules: # Add rule to env_provider transpiler = Transpiler(env_provider) try: transpiler.load(dumps(akashic_rule["rule"], indent=True)) env_provider.insert_rule(transpiler.rule.rule_name, transpiler.tranpiled_rule) mongo.db.rules.update_one( {"rule-name": akashic_rule["rule"]["rule-name"]}, {"$set": { "active": True }}) except AkashicError as e: return response(None, e.message, e.line, e.col, RespType.ERROR) message = "Engine has finished loading rules " \ "from database." return response(None, message, 0, 0, RespType.SUCCESS)
def create_rule_direct(): akashic_rule = request.json transpiler = Transpiler(env_provider) try: transpiler.load(dumps(akashic_rule, indent=True)) env_provider.insert_rule(akashic_rule["rule-name"], transpiler.tranpiled_rule) except AkashicError as e: return response(akashic_rule, e.message, e.line, e.col, RespType.ERROR) message = "New rule with rule-name '{0}' is successfully created." \ .format(akashic_rule['rule-name']) return response(akashic_rule, message, 0, 0, RespType.SUCCESS)
def update_rule(old_rule_name): # Get JSON data akashic_rule = request.json # Check if DSD with given model-id exists foundRule = mongo.db.rules.find_one( {'rule-name': { '$eq': old_rule_name }}) if not foundRule: message = "Rule with given rule-name does not exists." return response(None, message, 0, 0, RespType.ERROR) # Remove old rule from from env_provider try: env_provider.remove_rule(old_rule_name) except AkashicError as e: pass # Transpile the rule transpiler = Transpiler(env_provider) try: transpiler.load(dumps(akashic_rule, indent=True)) except AkashicError as e: return response(akashic_rule, e.message, e.line, e.col, RespType.ERROR) # Create RULE entry for mongodb rule_entry = {} rule_entry['rule-name'] = akashic_rule['rule-name'] rule_entry['salience'] = akashic_rule['salience'] rule_entry['active'] = False rule_entry['rule'] = akashic_rule rule_entry['clips-code'] = transpiler.tranpiled_rule rule_entry['hash'] = hashlib.sha256(dumps(akashic_rule, indent=True) \ .encode('utf-8')).hexdigest() # Replace old db entry with new one mongo.db.rules.replace_one({"rule-name": old_rule_name}, rule_entry) message = "Rule with rule-name '{0}' is successfully updated." \ .format(old_rule_name) return response(rule_entry, message, 0, 0, RespType.SUCCESS)
def create_rule(): akashic_rule = request.json # Check if rule with same name already exists foundRule = mongo.db.rules.find_one( {'rule-name': { '$eq': akashic_rule['rule-name'] }}) if foundRule != None: message = "Rule with given rule-name already exists." return response(None, message, 0, 0, RespType.ERROR) # Transpile the rule transpiler = Transpiler(env_provider) try: transpiler.load(dumps(akashic_rule, indent=True)) except AkashicError as e: return response(akashic_rule, e.message, e.line, e.col, RespType.ERROR) # Create RULE entry for mongodb rule_entry = {} rule_entry['rule-name'] = akashic_rule['rule-name'] rule_entry['salience'] = akashic_rule['salience'] rule_entry['active'] = False rule_entry['rule'] = akashic_rule rule_entry['clips-code'] = transpiler.tranpiled_rule rule_entry['hash'] = hashlib.sha256(dumps(akashic_rule, indent=True) \ .encode('utf-8')).hexdigest() # Insert new db entry mongo.db.rules.insert_one(rule_entry) message = "New rule with rule-name '{0}' is successfully created." \ .format(akashic_rule['rule-name']) return response(rule_entry, message, 0, 0, RespType.SUCCESS)
def insert_system_rules(self): transpiler = Transpiler(self) transpiler.load(REMOVE_RULE) self.insert_rule(transpiler.rule.rule_name, transpiler.tranpiled_rule)
def delete_func_call(self, *args): args = map(lambda arg: arg.replace('"', ''), args) args = list(args) self.print_args(args, "DELETE") MODEL_ID_POS = 0 REFLECT_INFO_POS = 2 REF_LEN_POS = 4 REF_START_POS = 5 # Obtain data from args data_provider = self.data_providers_map[args[MODEL_ID_POS]] reflect_on_web = string_to_py_type(args[REFLECT_INFO_POS], "BOOLEAN") ref_len = string_to_py_type(args[REF_LEN_POS], "INTEGER") # Build and deploy modification rule primary_key_field_name = \ self.get_primary_key_field(data_provider).field_name primary_key_field_value = self.get_field_value_from_args( args[REF_START_POS:REF_START_POS+ref_len], primary_key_field_name ) rhs = """{{ "?to_delete<-": "[{0}.{1} == {2}]" }}""".format( data_provider.dsd.model_id, str(primary_key_field_name), str(primary_key_field_value).replace('"', "'") ) lhs = """{{ "clips": "{0}" }}""".format( "(retract ?to_delete)" ) tmp_delete_rule = GENERIC_RULE.format( "__delete_fact_" + str(uuid.uuid4()).replace('-', ''), "\"system\"", "true", rhs, lhs ) if self.debug: print("\nDELETION RULE: " + tmp_delete_rule) print("\nDEL. RULE TRANSPILATION PRINT:") transpiler = Transpiler(self.env_provider) try: transpiler.load(tmp_delete_rule) except AkashicError as ae: print(ae.message) self.env_provider.insert_rule(transpiler.rule.rule_name, transpiler.tranpiled_rule) # Reflect modification on web if required if reflect_on_web: url_map_args = self.ref_arg_list_to_url_map( args[REF_START_POS:REF_START_POS+ref_len], data_provider.dsd.apis.update ) response_obj = data_provider.delete(**url_map_args) if self.debug: print("\nMAP: " + str(url_map_args)) print("\nDELETION RESPONSE:\n" + str(response_obj) + "\n\n") # Print all facts if self.debug: print("FACTS - print from bridge:") for f in self.env_provider.env.facts(): print("---------") print(f) print("****") return 0
def test_rule_transpiler(): # Create new env_provider env_provider = EnvProvider() # Setup User data provider this_folder = dirname(__file__) sample_path = abspath( join(this_folder, '..', 'test', 'samples', 'ads', 'user_dsd.json')) dsd_string = None with open(sample_path, 'r') as sample: dsd_string = sample.read() user_data_provider = DataProvider(env_provider) user_data_provider.load(dsd_string) user_data_provider.setup() # Setup Course data provider this_folder = dirname(__file__) sample_path = abspath( join(this_folder, '..', 'test', 'samples', 'ads', 'course_dsd.json')) dsd_string = None with open(sample_path, 'r') as sample: dsd_string = sample.read() course_data_provider = DataProvider(env_provider) course_data_provider.load(dsd_string) course_data_provider.setup() # Insert data providers in env provider env_provider.insert_data_provider(user_data_provider) env_provider.insert_data_provider(course_data_provider) # Setup akashic transpiler transpiler = Transpiler(env_provider) # Load Akashic rule #-------------------- # simple_return # time_return # rhs_return # rhs_create # rhs_update # rhs_update_pure # rhs_delete # test_assistance # test_count this_folder = dirname(__file__) sample_path = abspath( join(this_folder, '..', 'test', 'samples', 'arules', 'test_assistance.json')) with open(sample_path, 'r') as sample: akashic_rule = sample.read() transpiler.load(akashic_rule) # Print transpiled LHS commands print("\n----------------") print("Transpiled Rule:") print() print(transpiler.tranpiled_rule) print("\n----------------") print("\n") # Insert transpiled rule in env_provider env_provider.insert_rule(transpiler.rule.rule_name, transpiler.tranpiled_rule) ##### ADD FACTS FROM THE WEB # Read users from DS multiple_courses = course_data_provider.read_multiple() # Generate CLIPS facts from JSON objects course_clips_facts = course_data_provider.generate_multiple_clips_facts( multiple_courses, 5) # Insert CLIPS facts in env_provider for u in course_clips_facts: env_provider.insert_fact(u) rule = env_provider.env.find_rule("Test_assistance") print("DELETABLE: " + str(rule.deletable)) rule.undefine() ###### RUN CLIPS ENGINE print("\n\n-> RUN 1\n*********************************" \ "***************************************" \ "***************************************" ) print("*********************************" \ "***************************************" \ "***************************************\n" ) # Run CLIPS engine env_provider.run() print("\n\nREUTRN DATA: ") for e in env_provider.get_return_data(): print(e) print("------------------------------") print("\n") print("\n") print("RULES: ") print("-------------------------START") for r in env_provider.env.rules(): print(r) print("-------------------------END") print("\n") print("FACTS: ") print("-------------------------START") for f in env_provider.env.facts(): print(f) print("-------------------------END") print("\n\n-> RUN 2\n*********************************" \ "***************************************" \ "***************************************" ) print("*********************************" \ "***************************************" \ "***************************************\n" ) # Run CLIPS engine env_provider.run() print("\n\nREUTRN DATA: ") for e in env_provider.get_return_data(): print(e) print("------------------------------") print("\n") print("\n") print("RULES: ") print("-------------------------START") for r in env_provider.env.rules(): print(r) print("-------------------------END") print("\n") print("FACTS: ") print("-------------------------START") for f in env_provider.env.facts(): print(f) print("-------------------------END")
def assist(): akashic_rule = request.json # Insert rule that needs assistance into engine transpiler = Transpiler(env_provider) try: transpiler.load(dumps(akashic_rule, indent=True)) env_provider.insert_rule(transpiler.rule.rule_name, transpiler.tranpiled_rule) except AkashicError as e: return response(akashic_rule, e.message, e.line, e.col, RespType.ERROR) # Run the engine is assistance mode / assistance session try: env_provider.run() except AkashicError as e: return response(None, e.message, e.line, e.col, RespType.ERROR) # Collect the reponses from the assistance session return_data_array = [] for ret in env_provider.return_data: return_data_array.append(loads(ret)) # Create the list of assistance query results # And the list of query rules to be removed #from the engine query_results = [] rules_to_remove = set() for ret in return_data_array: if ret["meta"]["tag"] == "query_return": query_results.append(ret) if ret["meta"]["tag"] == "query_rule_name_return": if "query_rule_name" in ret["data"]: rules_to_remove.add(ret["data"]["query_rule_name"]) # Remove the rules colelcted in list above for rule_name in rules_to_remove: try: env_provider.remove_rule(rule_name) except AkashicError as e: return response(None, e.message, e.line, e.col, RespType.ERROR) # Turn off engine assistance mode so that all other # non-assistance related rules can run in next esssion env_provider.execute( "(do-for-all-facts ((?ao __AssistanceOn)) TRUE (retract ?ao) )") # Undefine assisted rule try: env_provider.remove_rule(akashic_rule['rule-name']) except AkashicError as e: pass # Create response and return resp = {} resp["query_results"] = query_results resp["rule"] = akashic_rule message = "Assistance is done. You can view get possible values for ???* values" return response(resp, message, 0, 0, RespType.SUCCESS)