نحوه نوشتن یک موتور قوانین اساسی در پایتون
در حالی که بسیاری از موتورهای قوانین موجود در پایتون وجود دارد، مانند چارچوب قوانین موتور شگفتانگیز، من فکر میکردم تمرین جالبی برای استفاده از ChatGPT برای کمک به من برای نوشتن موتور قوانین اساسی خودم از ابتدا خواهد بود. بنابراین، بدون بحث بیشتر – من PYROSE – موتور سیستم عامل مبتنی بر قانون پایتون را به شما ارائه می کنم.
ساختار اصلی سیستم قوانین ما به شرح زیر است. در پایه اصلی موتور ما حقایق داریم. Factها اشیاء ساده ای هستند که نشان دهنده اطلاعاتی هستند که ما می خواهیم در سیستم خود ذخیره شود و می توانند حاوی هر نوع اطلاعاتی باشند که مربوط به طراحی محدودیت هایی است که موتور قوانین ما بر اساس آن کار می کند. اجازه دهید با تعریف یک ساختار بسیار ساده برای Facts شروع کنیم
from typing import Any
class Fact:
def __init__(self, **kwargs: Any):
self.__dict__.update(kwargs)
در اینجا ما یک شی بسیار ساده تعریف می کنیم که می تواند با هر تعداد آرگومان کلمه کلیدی برای تعریف واقعیت ما نمونه سازی شود. سپس شیء خود را با استفاده از به روز رسانی می کنیم self.__dict__.update
روشی برای اضافه کردن ویژگی هایی به شی ما مربوط به کلمات کلیدی ارسال شده به اولیه ساز. ما می توانیم یک واقعیت را به صورت زیر مقداردهی کنیم
person_fact = Fact(name="John Brown", age="35", occuptation="Software Developer")
دسترسی به یک ویژگی با استفاده از نماد نقطه به همان اندازه ساده است که گویی به عضو یا روشی روی شی دسترسی دارید.
person_fact.age # Returns 35
اکنون که شی Fact خود را ایجاد کرده ایم، باید یک شرط تعریف کنیم تا شی Fact خود را بر اساس آن اعمال کنیم. شرایط ما در طراحی بسیار ساده و همچنین برای شروع با آن است. مقداردهی اولیه دو پارامتر دارد، یک نام و یک تابع ارزیابی. تابع ارزیابی به یک Fact اعمال می شود و یک bool را برمی گرداند. همچنین شامل یک متد ارزیابی میشود که یک Fact را میگیرد و یک bool برمیگرداند و اشیاء ارزیابی_function را در Fact مینامد. در اینجا طرح کلی کلاس Condition ما است:
from rule_engine.fact import Fact
from typing import Callable, Any, Dict, List
class Condition:
def __init__(self, name: str, evaluation_function: Callable[[Fact], bool]):
self.name = name
self.eval_func = evaluation_function
def evaluate(self, fact: Fact) -> bool:
return self.eval_func(fact)
با پیروی از یک مورد مشابه، می توانیم کلاس Action خود را تعریف کنیم. یک کلاس Action یک پارامتر نام و یک پارامتر Callable را در مقداردهی اولیه خود می گیرد. Callable مربوط به تابع اجرای Action است، در صورتی که همه شرایط قانون True باشند، اجرا می شود. همچنین حاوی یک متد execute است که تابع execute را در Fact داده شده فراخوانی می کند و در نتیجه یک نوع None می دهد. در اینجا تعریف کلاس Action آمده است:
from typing import Callable, Any, Dict, List
from rule_engine.fact import Fact
class Action:
def __init__(self, name: str, execution_function: Callable[[Fact], None]):
self.name = name
self.exec_func = execution_function
def execute(self, fact: Fact) -> None:
self.exec_func(fact)
تا کنون ما واقعیت، شرایط و عمل خود را تعریف کرده ایم. ما می توانیم اینها را با هم ترکیب کنیم تا کلاس Rule خود را تشکیل دهیم. این نیروی محرکه اصلی موتور ما خواهد بود. کلاس Rule در ابتدا با یک Action و Condition ساخته می شود. دو متد add_condition و add_action به شما این امکان را میدهند تا در صورت نیاز شرایط و اقدامات اضافی را به Rule اضافه کنید.
در نهایت، روش سوم، ارزیابی، فهرستی از حقایق را در بر می گیرد. یک fact_generator را تعریف می کند که فهرستی از شرایط و فهرستی از حقایق را می گیرد. برای هر واقعیت، هر یک از شرایط eval_func را در برابر واقعیت ترسیم می کند. سپس این لیست را به یک مقدار بولی تقلیل می دهد و اگر این مقدار درست باشد، واقعیت را به دست می دهیم.
سپس تابع fact_generator را فراخوانی میکنیم، آن را در لیستی قرار میدهیم تا فهرستی از تمام حقایق True بدست آوریم، و اگر طول آن بزرگتر از 0 باشد، در لیست حقایق واقعی تکرار میکنیم. برای هر واقعیت واقعی، فهرستی از اقدامات قوانین را تکرار می کنیم و exec_func عمل را بر روی واقعیت واقعی فراخوانی می کنیم.
تعریف کامل کلاس Rule به شرح زیر است:
from rule_engine.condition import Condition
from rule_engine.action import Action
from rule_engine.fact import Fact
from typing import Any, List
from functools import reduce
from rule_engine.condition import Condition
from rule_engine.action import Action
from rule_engine.fact import Fact
from typing import Any, List
from functools import reduce
class Rule:
def __init__(self, condition: Condition, action: Action):
self.conditions = [condition]
self.actions = [action]
def add_condition(self, condition: Condition) -> None:
self.conditions.append(condition)
def add_action(self, action: Action) -> None:
self.actions.append(action)
def evaluate(self, facts: List[Fact]) -> Any:
def fact_generator(conditions: List[Condition], facts: List[Fact]):
all_conditions_true = True
for fact in facts:
results = map(lambda condition: condition.eval_func(fact), conditions)
all_conditions_true = reduce(lambda x, y: x and y, results)
if all_conditions_true:
yield fact
true_facts = list(fact_generator(self.conditions, facts))
if len(true_facts) > 0:
for fact in true_facts:
for action in self.actions:
action.exec_func(fact)
می توانید از موتور قانون به صورت زیر استفاده کنید:
from rule_engine.fact import Fact
from rule_engine.condition import Condition
from rule_engine.action import Action
from rule_engine.rule import Rule
age_cond = Condition(name="Age>=21", evaluation_function=lambda fact: fact.age >= 21)
occupation_cond = Condition(name="Occupation==Software Developer", evaluation_function=lambda fact: fact.occupation == "Software Developer")
print_action = Action(name="Print Fact", execution_function=lambda fact: print("Name: {} Age: {} Occupation: {}".format(fact.name, fact.age, fact.occupation)))
john = Fact(age=25,name="John Brown", occupation="Software Developer")
sarah = Fact(age=35,name="Sarah Purple", occupation="Data Engineer")
barry = Fact(age=27, name="Barry White", occupation="Software Developer")
rule = Rule(condition=age_cond, action=print_action)
rule.add_condition(occupation_cond)
rule.evaluate([john, sarah, barry])
در مجموع، این یک نسخه ی نمایشی بسیار ابتدایی از یک موتور قوانین بسیار ساده است. با این حال، من فکر میکنم که قطعاً میتوان آن را به روشهای مختلف ساخت و بهبود بخشید، بنابراین امیدوارم از خواندن و استفاده از آنچه آموختهاید در پروژههای خود لذت برده باشید. اگر سوال، نظر، پیشنهاد یا ایده ای دارید، لطفا با من تماس بگیرید. ممنون که خواندید.