如何在Python Experta框架中按指定顺序执行专家系统提问?
解决Experta专家系统规则执行顺序问题
你的问题核心是让greet相关规则(姓名、地点提问+问候)先执行完毕,再触发info相关规则(号码、身高提问+信息输出),确实可以通过salience(规则优先级)来实现,也可以通过控制事实的触发时机来完成,以下是两种可行方案:
方案一:使用salience设置规则优先级
Experta中规则默认优先级为0,数值越高的规则会被优先匹配执行。给greet相关规则设置更高的salience值,让它们先完成执行,再处理info规则。
修改后的代码如下(标注了关键修改点):
from experta import * class Greetings(KnowledgeEngine): @DefFacts() def _initial_action(self): yield Fact(action="greet") yield Fact(action="info") # 给greet相关规则设置高优先级salience=10 @Rule(Fact(action='greet'), NOT(Fact(name=W())), salience=10) def ask_name(self): self.declare(Fact(name=input("What's your name? "))) @Rule(Fact(action='greet'), NOT(Fact(location=W())), salience=10) def ask_location(self): self.declare(Fact(location=input("Where are you? "))) @Rule(Fact(action='greet'), Fact(name=MATCH.name), Fact(location=MATCH.location), salience=10) def greet(self, name, location): print("Hi %s! How is the weather in %s?" % (name, location)) # 给info相关规则设置较低优先级salience=5 @Rule(Fact(action='info'), NOT(Fact(number=W())), salience=5) def ask_number(self): self.declare(Fact(number=input("What's your number? "))) # 修正原代码的输入提示错误 @Rule(Fact(action='info'), NOT(Fact(height=W())), salience=5) def ask_height(self): self.declare(Fact(height=input("What's your height? "))) @Rule(Fact(action='info'), Fact(number=MATCH.number), Fact(height=MATCH.height), salience=5) def info(self, number, height): print("Your phone number is %s! Your height is %s." % (number, height)) if __name__ == "__main__": system = Greetings() while True: system.reset() system.run() print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") print("Do you want to talk again?") if input().lower() == 'no': break
方案二:控制事实触发时机(不依赖salience)
不在初始事实中直接生成info的Fact,而是等greet流程完成后,在greet方法中主动声明info的事实,这样自然会先完成问候流程,再启动信息收集流程。
修改后的代码:
from experta import * class Greetings(KnowledgeEngine): @DefFacts() def _initial_action(self): # 只初始化greet的事实 yield Fact(action="greet") @Rule(Fact(action='greet'), NOT(Fact(name=W()))) def ask_name(self): self.declare(Fact(name=input("What's your name? "))) @Rule(Fact(action='greet'), NOT(Fact(location=W()))) def ask_location(self): self.declare(Fact(location=input("Where are you? "))) @Rule(Fact(action='greet'), Fact(name=MATCH.name), Fact(location=MATCH.location)) def greet(self, name, location): print("Hi %s! How is the weather in %s?" % (name, location)) # 问候完成后,声明info的事实,触发后续规则 self.declare(Fact(action="info")) @Rule(Fact(action='info'), NOT(Fact(number=W()))) def ask_number(self): self.declare(Fact(number=input("What's your number? "))) # 修正原代码的输入提示错误 @Rule(Fact(action='info'), NOT(Fact(height=W()))) def ask_height(self): self.declare(Fact(height=input("What's your height? "))) @Rule(Fact(action='info'), Fact(number=MATCH.number), Fact(height=MATCH.height)) def info(self, number, height): print("Your phone number is %s! Your height is %s." % (number, height)) if __name__ == "__main__": system = Greetings() while True: system.reset() system.run() print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") print("Do you want to talk again?") if input().lower() == 'no': break
注意:原代码中ask_height方法的输入提示写错成了"Where are you? ",两种方案中都已修正为正确的"What's your height? "。
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

