jruizgit / rules

Durable Rules Engine
MIT License
1.14k stars 209 forks source link

Issue with multiple asserted facts similarly formatted #390

Open nateand opened 2 years ago

nateand commented 2 years ago

I'm using your library in python quite successfully, but I have walked into a situation that is either a bug or a misuse on my part and I would like to see if anyone can take a look at this. I'm building the ruleset with JSON, I've got the following four asserted facts:

{'message_type': 'info', 'id': 'FT_28', 'rfx': True, 'aco': False, 'fs': False, 'ts': False, 'dpc': 0, 'dm': True}, {'message_type': 'info', 'id': 'FT_30', 'rfx': False, 'aco': True, 'fs': False, 'ts': False, 'dpc': 1, 'dm': False}, {'message_type': 'priority', 'p_id': 'FT_30', 'thr': 7, 'u_t': False, 'ran': 399.98815459329694, 'unk_ran': False}, {'message_type': 'Status', 'status_id': 'f01', 's_status': True, 'u_id': 'FT_28', 'mode': 't-a'}

I then have the following relevant rule: `"r_3": {

"all": [{
    "tar": {
        "$and": [{
            "message_type": "priority"
        }, {
            "u_t" : false
        }, {
            "$or" : [{
                "unk_ran" : true
            }, {
                "$and": [{
                    "$gt": {
                        "ran": 0
                    }
                }, {
                    "$lt": {
                        "ran": 1000
                    }
                }]
            }]
        }]
    }
}, {
    "check_status": {
        "$and": [{
            "message_type": "Status"
        }, {
            "$neq": {
                "mode" : "n-d"
            }
        }, {
            "$neq": {
                "u_id" : {
                    "tar": "p_id"
                }
            }
        }]
    }
}, {
    "s_info": {
        "$and": [{
            "message_type": "info"
        }, {
            "$or": [{
                "rfx": true
            }, {
                "aco" : true
            }]
        }, {
            "id" : {
                "tar": "p_id"
            }
        }]
    }
}, {
    "cur_s_info": {
        "$and": [{
            "message_type": "info"
        }, {
            "dm" : false
        }, {
            "$lt" :{
                "dpc" : 2
            }
        }, {
            "id" : {
                "check_status": "u_id"
            }
        }, {
    "$neq" : {                
            "id" : {
                    "check_status": "u_id"
                 }
    }
        }]
    }
}], ...`

If you look at the end, you'll notice I'm calling both comparisons id == check_status.u_id and id != check_status.u_id. This was done to highlight the extreme case of this issue. In this case, it is still passing the check and satisfying the rule. My original rule didn't have the "neq" condition in it, that was something I added to verify I truly was getting the comparison incorrectly. My goal was to evaluate the "info" fact with the id corresponding to the "Status" fact, but it is clearly mixing the two up as needed to satisfy the rule. Is there a way to force the comparison to be within the same fact? I would like to check that the fact with "message_type" of "info" and the id corresponding to the status message have the "dm" and "dpc" fields correctly set up to satisfy my conditions, rather than ANY "info" message_type being used.

I have determined a work around, but I wanted to verify if this issue was on my end or if there was a way to make this sort of functionality work without my work around.