示例#1
0
    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
示例#2
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)
示例#3
0
    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)
示例#4
0
    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)
示例#5
0
    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)
示例#6
0
 def insert_system_rules(self):
     transpiler = Transpiler(self)
     transpiler.load(REMOVE_RULE)
     self.insert_rule(transpiler.rule.rule_name, transpiler.tranpiled_rule)
示例#7
0
    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
示例#8
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")
示例#9
0
    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)