You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySWIP访问SWI-Prolog知识库报错:atom_chars/2参数未充分实例化

问题:PySWIP调用consult时出现instantiation_error错误

环境配置

  • macOS 13.1
  • Python 3.11
  • PySWIP 0.2.10
  • x86_64-darwin版本SWI-Prolog 9.0.4

错误详情

运行Python脚本调用prolog.consult("knowledge_base.pl")时触发以下错误:

ERROR: atom_chars/2: Arguments are not sufficiently instantiated
Traceback (most recent call last):
File "/Users/user/PycharmProjects/ExpertSystem/venv/expert_system.py", line 5, in 
prolog.consult("knowledge_base.pl")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/user/PycharmProjects/ExpertSystem/venv/lib/python3.11/site-packages/pyswip/prolog.py", line 156, in consult
next(cls.query(filename.join(["consult('", "')"]), catcherrors=catcherrors))
File "/Users/user/PycharmProjects/ExpertSystem/venv/lib/python3.11/site-packages/pyswip/prolog.py", line 126, in __call__
raise PrologError("".join(["Caused by: '", query, "'. ",
pyswip.prolog.PrologError: Caused by: 'consult('knowledge_base.pl')'. Returned: 'error(instantiation_error, context(:(system, /(atom_chars, 2)), _654))'.

Prolog知识库代码

% Facts
% Regular Covid virus symptoms
covid_symptom(fever).
covid_symptom(cough).
covid_symptom(shortness_of_breath).
covid_symptom(fatigue).
covid_symptom(loss_of_taste_or_smell).

% Kraken (XBB.1.5) variant symptoms
kraken_symptom(intense_headache).
kraken_symptom(chest_pain).
kraken_symptom(sudden_loss_of_hearing).

% Omicron Variant symptoms
omicron_symptom(sore_throat).
omicron_symptom(rapid_heartbeat).
omicron_symptom(skin_rash).

% Underlying conditions
underlying_condition(diabetes).
underlying_condition(hypertension).
underlying_condition(asthma).
underlying_condition(cardiovascular_disease).

% Rules
% Person is at risk of Covid if they have Covid symptoms and risk factors (underlying conditions)
risk_of_covid(Person) :-
    has_covid_symptom(Person),
    has_risk_factor(Person).

% Person has Covid symptom if they have a symptom that is a Covid symptom
has_covid_symptom(Person) :-
    symptom(Person, Symptom),
    covid_symptom(Symptom).

% Person has a risk factor if they have a condition that is an underlying condition
has_risk_factor(Person) :-
    condition(Person, Condition),
    underlying_condition(Condition).

% Person is at risk of Kraken variant if they have Kraken symptoms and risk factors (underlying conditions)
risk_of_kraken_variant(Person) :-
    has_kraken_symptom(Person),
    has_risk_factor(Person).

% Person has Kraken symptom if they have a symptom that is a Kraken symptom
has_kraken_symptom(Person) :-
    symptom(Person, Symptom),
    kraken_symptom(Symptom).

% Person is at risk of Omicron variant if they have Omicron symptoms and risk factors (underlying conditions)
risk_of_omicron_variant(Person) :-
    has_omicron_symptom(Person),
    has_risk_factor(Person).

% Person has Omicron symptom if they have a symptom that is an Omicron symptom
has_omicron_symptom(Person) :-
    symptom(Person, Symptom),
    omicron_symptom(Symptom).

% Person has low blood pressure if their systolic and diastolic readings are below certain thresholds
low_blood_pressure(Systolic, Diastolic) :-
    Systolic < 90,
    Diastolic < 60.

% Person has high blood pressure if their systolic or diastolic readings are above certain thresholds
high_blood_pressure(Systolic, Diastolic) :-
    Systolic > 129,
    Diastolic > 79.

% Conversion of temperature from Fahrenheit to Celsius
convert_fahrenheit_to_celsius(F, C) :-
    C is (F - 32) * 5 / 9.

% Person has fever if their temperature in Celsius is above a certain threshold
has_fever(Person) :-
    temperature_celsius(Person, Temp),
    Temp >= 37.5.

% Person has Covid symptoms if they have a fever or another Covid symptom
has_covid_symptom(Person) :-
    has_fever(Person);
    symptom(Person, Symptom),
    covid_symptom(Symptom).

% Rules for counting mild and severe symptoms are unchanged
mild_symptom_count(Count) :-
    findall(Person, (has_covid_symptom(Person), symptom(Person, S), mild_symptom(S)), Persons),
    length(Persons, Count).

severe_symptom_count(Count) :-
    findall(Person, (has_covid_symptom(Person), symptom(Person, S), severe_symptom(S)), Persons),
    length(Persons, Count).

% Define your rules for identifying Kraken and Omicron variants here
has_kraken_variant(Person) :-
    risk_of_kraken_variant(Person).

has_omicron_variant(Person) :-
    risk_of_omicron_variant(Person).

% Rules for counting Kraken and Omicron variants
kraken_variant_count(Count) :-
    findall(Person, has_kraken_variant(Person), Persons),
    length(Persons, Count).

omicron_variant_count(Count) :-
    findall(Person, has_omicron_variant(Person), Persons),
    length(Persons, Count).

% Rules for counting persons with underlying conditions
persons_with_conditions_count(Count) :-
    findall(Person, (has_covid_symptom(Person), condition(Person, _)), Persons),
    length(Persons, Count).

% Rule for finding top 3 underlying conditions
top_conditions(Top3) :-
    findall((Count, Condition), (condition(_, Condition), aggregate(count, Person, condition(Person, Condition), Count)), Counts),
    sort(Counts, SortedCounts),
    reverse(SortedCounts, DescCounts),
    length(DescCounts, Length),
    (Length >= 3 -> length(Top3, 3); length(Top3, Length)),
    append(Top3, _, DescCounts).

Python代码

import sys
from pyswip import Prolog

prolog = Prolog()
prolog.consult("knowledge_base.pl")  # Load the Prolog knowledge base

def consult_knowledge_base(query, variable=None):
    results = list(prolog.query(query))
    if variable:
        return [result[variable] for result in results]
    else:
        return bool(results)

def add_knowledge(fact):
    prolog.assertz(fact)


def add_underlying_condition(person, condition):
    fact = f"condition({person}, {condition})"
    add_knowledge(fact)


def add_temperature_fahrenheit(person, temperature_f):
    temperature_c = (temperature_f - 32) * 5 / 9
    fact = f"temperature_celsius({person}, {temperature_c})"
    add_knowledge(fact)


def add_blood_pressure(person, systolic, diastolic):
    fact_systolic = f"systolic_bp({person}, {systolic})"
    fact_diastolic = f"diastolic_bp({person}, {diastolic})"
    add_knowledge(fact_systolic)
    add_knowledge(fact_diastolic)


def ask_questions(person):
    while True:
        print("\nOptions:")
        print("1. Add underlying condition")
        print("2. Add temperature (Fahrenheit)")
        print("3. Add symptom")
        print("4. Add blood pressure")
        print("5. Done")

        choice = input("Enter your choice: ")

        if choice == "1":
            condition = input("Enter underlying condition: ")
            add_underlying_condition(person, condition)
        elif choice == "2":
            temperature_f = float(input("Enter temperature in Fahrenheit: "))
            add_temperature_fahrenheit(person, temperature_f)
        elif choice == "3":
            symptom = input("Enter symptom: ")
            add_symptom(person, symptom)
        elif choice == "4":
            systolic = float(input("Enter systolic blood pressure (mm Hg): "))
            diastolic = float(input("Enter diastolic blood pressure (mm Hg): "))
            add_blood_pressure(person, systolic, diastolic)
        elif choice == "5":
            break
        else:
            print("Invalid choice. Please try again.")


def add_symptom(person, symptom):
    fact = f"symptom({person}, {symptom})"
    add_knowledge(fact)


def diagnose(person):
    query_regular_covid = f"risk_of_covid({person})"
    query_kraken_variant = f"risk_of_kraken_variant({person})"
    query_omicron_variant = f"risk_of_omicron_variant({person})"

    diagnosis = {}

    if list(prolog.query(query_regular_covid)):
        diagnosis["Regular COVID-19"] = True
    else:
        diagnosis["Regular COVID-19"] = False

    if list(prolog.query(query_kraken_variant)):
        diagnosis["Kraken (XBB.1.5) variant"] = True
    else:
        diagnosis["Kraken (XBB.1.5) variant"] = False

    if list(prolog.query(query_omicron_variant)):
        diagnosis["Omicron variant"] = True
    else:
        diagnosis["Omicron variant"] = False

    diagnosis["at_risk_of_covid"] = consult_knowledge_base(f"at_risk_of_covid({person})")
    diagnosis["short_term_action"] = consult_knowledge_base(f"short_term_action({person}, Action)", "Action")
    diagnosis["long_term_action"] = consult_knowledge_base(f"long_term_action({person}, Action)", "Action")
    return diagnosis
def display_statistics():
    total_count = consult_knowledge_base("total_persons_diagnosed(Total)", "Total")
    mild_count = consult_knowledge_base("mild_symptom_count(Count)", "Count")
    severe_count = consult_knowledge_base("severe_symptom_count(Count)", "Count")
    kraken_count = consult_knowledge_base("kraken_variant_count(Count)", "Count")
    omicron_count = consult_knowledge_base("omicron_variant_count(Count)", "Count")
    conditions_count = consult_knowledge_base("persons_with_conditions_count(Count)", "Count")
    top_conditions = consult_knowledge_base("top_conditions(Conditions)", "Conditions")

    print("\nCOVID-19 Statistics:")
    print(f"Percentage of persons with mild symptoms: {100 * mild_count / total_count:.2f}%")
    print(f"Percentage of persons with severe symptoms: {100 * severe_count / total_count:.2f}%")
    print(f"Percentage of persons with the Kraken (XBB.1.5) variant: {100 * kraken_count / total_count:.2f}%")
    print(f"Percentage of persons with the Omicron Variant: {100 * omicron_count / total_count:.2f}%")
    print(f"Percentage of affected persons with underlying conditions: {100 * conditions_count / total_count:.2f}%")
    print(f"Top 3 underlying conditions: {', '.join(top_conditions)}")
    # Check for any spikes or unusual increases in reports

    spike_thresholds = {
        'mild_symptoms': 30,
        'severe_symptoms': 10,
        'kraken_variant': 15,
        'omicron_variant': 15,
        'underlying_conditions': 40
    }

    spikes = []

    if 100 * mild_count / total_count > spike_thresholds['mild_symptoms']:
        spikes.append("mild symptoms")

    if 100 * severe_count / total_count > spike_thresholds['severe_symptoms']:
        spikes.append("severe symptoms")

    if 100 * kraken_count / total_count > spike_thresholds['kraken_variant']:
        spikes.append("Kraken (XBB.1.5) variant")

    if 100 * omicron_count / total_count > spike_thresholds['omicron_variant']:
        spikes.append("Omicron variant")

    if 100 * conditions_count / total_count > spike_thresholds['underlying_conditions']:
        spikes.append("affected persons with underlying conditions")

    if spikes:
        print("\nAlert:")
        print(
            "There is an unusual increase in reports of persons prone to having (or possibly has) COVID-19 with the following characteristics:")
        for spike in spikes:
            print(f"- {spike}")
        print("Please take necessary actions and inform the relevant authorities.")

排查情况

已确认错误与知识库代码无关,问题出在PySWIP层面。尝试重装PySWIP十次仍无法解决,无法定位具体原因,确定问题与PySWIP相关。


内容的提问来源于stack exchange,提问作者Demali Gregg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 14:39:54