Jess诊断GUI应用仅显示首个问题,答案未记录的故障排查
Hey there! Let's dig into why your Jess diagnostic GUI is stuck on the first question and not tracking answers properly. I've spotted several key issues in your simplified code that are causing these problems:
1. Uncontrolled Initial Question Assertions
Your four questions_basique_X rules all have (declare (auto-focus TRUE)) and no triggering conditions. That means when the engine starts, all four rules fire at the same time, asserting (ask age), (ask poids), and duplicate (ask symptome_majeur_1) facts immediately. This overwhelms the ask::ask-question-by-id rule, which can only handle one question at a time—leaving subsequent questions blocked.
Fix: Make basic questions fire in sequence, each relying on the previous question's answer existing:
(defrule MAIN::questions_basique_1 (declare (auto-focus TRUE)) ;; Trigger only if no basic question answers exist yet (not (MAIN::reponses (ident ?&:(member ?id (age poids symptome_majeur_1))))) => (assert (ask age))) (defrule MAIN::questions_basique_2 (declare (auto-focus TRUE)) ;; Trigger only after age is answered (MAIN::reponses (ident age)) (not (MAIN::reponses (ident poids))) => (assert (ask poids))) (defrule MAIN::questions_basique_3 (declare (auto-focus TRUE)) ;; Trigger only after poids is answered (MAIN::reponses (ident poids)) (not (MAIN::reponses (ident symptome_majeur_1))) => (assert (ask symptome_majeur_1)))
(Note: Your original questions_basique_4 duplicates symptome_majeur_1—update it to the next unique question ID.)
2. Incomplete collect-user-input Rule
Your ask::collect-user-input rule cuts off before critical steps that close the loop on user input:
- It doesn't remove the processed
askanduser-inputfacts - It doesn't trigger the engine to run subsequent rules after saving the answer
Fix the full rule:
(defrule ask::collect-user-input (declare (auto-focus TRUE)) (MAIN::questions (ident ?id) (texte ?text) (type ?type)(valid $?valid)) (not (MAIN::reponses (ident ?id))) ?user <- (user-input ?input) ?ask <- (MAIN::ask ?id) => (if (is-of-type ?input ?type ?valid) then ;; Save valid answer (assert (MAIN::reponses (ident ?id) (texte ?input))) ;; Clean up processed facts (retract ?ask ?user) ;; Kick off next rules ((engine) run) else ;; Retry invalid input (optional: add error message here) (ask-patient ?text ?type ?valid) (retract ?user) ))
3. Missing user-input Fact Trigger
Your GUI code (not fully shown) needs to assert a (user-input ?answer) fact when the user clicks an OK button. This is how the Jess engine gets notified of user input. For example, add this to your button's ActionListener:
// Example for text input OK button ?*afield-ok*.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String input = ?*afield*.getText(); // Send input to Jess engine engine.assertString("(user-input \"" + input + "\")"); } });
4. Duplicate Rules & Typo Checks
- Remove the duplicate
questions_basique_4rule that repeatssymptome_majeur_1 - Fix inconsistent French spellings (e.g.,
dypn茅e_brutevsdyspn茅)—mismatched IDs will break rule matching
Final Testing Steps
- Start with
(reset)(safe since you set(set-reset-globals FALSE)) - Run
(run)to trigger the first question - Verify that each valid answer clears the current
askfact and triggers the next rule in sequence
内容的提问来源于stack exchange,提问作者Nadh Hely

