Experto en enfermedades (versión en D)

Descripción del contenido de la página

Sistema experto sobre enfermedades, escrito en D.

Etiquetas:

Código fuente

// main.d
//
// This file is part of Experto en enfermedades (Expert on diseases)

// Last modified 20250812T1903+0200.

/*

Copyright (C) 1985, Chris Naylor: Sinclair BASIC code included in his book
"Build Your Own Expert System" (Sigma Press, 1985).

Copyright (C) 1988, 1989, Marcos Cruz (programandala.net): SuperBASIC version
(http:///programandala.net/es.programa.sistema_experto_sobre_enfermedades.html).

Copyright (C) 2023, 2024, Marcos Cruz (programandala.net): Odin version.

Copyright (C) 2024, 2025, Marcos Cruz (programandala.net): SBASIC version.

Copyright (C) 2025, Marcos Cruz (programandala.net): V version.

Copyright (C) 2025, Marcos Cruz (programandala.net): D version.

This program is licensed under a BSD 2-Clause License
(https://opensource.org/license/bsd-2-clause/). See the <LICENSE.txt> file.

*/

// ==========================================================================

module main;

import std.conv :
    to;
import std.stdio :
    writefln,
    writeln;
import std.format :
    format;
import std.math :
    abs,
    round;

import par = ditto.par;
import terminal = ditto.term;

import data;
import user_input;
import version_number;

/// Name of the program.

enum string TITLE = "Experto en enfermedades";

/// Working modes.  The random and value modes are available only when the
/// program is compiled with the `-debug` option.

enum Mode { Normal, Random_Demo, Value_Demo }

/// Current working mode, normal by default.

Mode mode = Mode.Normal;

/// Value of the answer used in demo mode.

int demo_value;

/// Init the program.

void init()
{
    // do not pause during the printing of the paragrahps
    par.max_lines_printed_before_a_pause = 0;
}

/// Consult the expert.

void consult()
{
    enum int DISEASES = 91;
    enum int SYMPTOMS = 68;

    double[DISEASES] max_prob = 0.0;
    double[DISEASES] min_prob = 0.0;
    double[DISEASES] prob = 0.0;
    bool[SYMPTOMS] asked;
    int[DISEASES] symptoms_count;
    int[DISEASES] symptoms_left;
    double[SYMPTOMS] value = 0.0;

    int answer_value;
    int hypothesis;

    double current_prob = 0.0;

    // Find the a priori probability and the rule values

    debug
    {
        writeln("Find the a priori probability and the rule values");
    }

    foreach (int disease_number; 0 .. DISEASES)
    {
        Disease disease = disease_data(disease_number);
        prob[disease_number] = disease.prob;
        current_prob = prob[disease_number];
        debug
        {
            writefln
            (
                "Disease #%s: \"%s\" (current prob: %s)",
                disease_number,
                disease.name,
                current_prob
            );
        }
        for (int disease_symptom = 0 ; true; disease_symptom += 1)
        {
            Symptom symptom = symptom_data(disease_number, disease_symptom);
            if (!symptom.ok)
            {
                break;
            }
            else
            {
                symptoms_left[disease_number] += 1;
                value[symptom.number] +=
                    abs
                    (
                        current_prob * symptom.pro_prob
                        / (
                            current_prob * symptom.pro_prob
                            + (1 - current_prob) * symptom.con_prob
                        )
                        -
                            current_prob * (1 - symptom.pro_prob)
                            / (
                                current_prob * (1 - symptom.pro_prob)
                                + (1 - current_prob) * (1 - symptom.con_prob)
                            )
                    );
                debug
                {
                    writefln
                    (
                        "Symptom #%s (value: %s)",
                        symptom.number,
                        value[symptom.number]
                    );
                }
            }
        }
        symptoms_count[disease_number] = symptoms_left[disease_number];
    }

    while (true)
    {
        // Find the most important symptom and ask about it;

        debug
        {
            writeln("Find the most important symptom and ask about it");
        }

        double min_value = 0.0;
        enum int NO_SYMPTOM = -1;
        auto symptom_to_ask_for = NO_SYMPTOM;
        foreach (int symptom_; 0 .. SYMPTOMS)
        {
            if (value[symptom_] > min_value)
            {
                symptom_to_ask_for = symptom_;
                min_value = value[symptom_];
                debug
                {
                    writefln
                    (
                        "Symptom to ask for: #%s, \"%s\" (value: %s)",
                        symptom_to_ask_for,
                        question(symptom_to_ask_for),
                        min_value
                    );
                }
            }
            value[symptom_] = 0;
        }
        if (symptom_to_ask_for == NO_SYMPTOM)
        {
            par.whole("No hay más preguntas.");
            return;
        }
        debug
        {
            if (mode == Mode.Normal)
            {
                terminal.clear_screen();
            }
        }
        par.whole(question(symptom_to_ask_for));
        final switch (mode)
        {
            case Mode.Random_Demo:
                answer_value = random_answer();
                par.whole(format("%s", answer_value));
                break;
            case Mode.Value_Demo:
                answer_value = demo_value;
                par.whole(format("%s", answer_value));
                break;
            case Mode.Normal:
                answer_value = user_answer();
        }
        asked[symptom_to_ask_for] = true;

        // Update the a priori probabilities

        debug
        {
            writeln("Update the a priori probabilities");
        }

        foreach (int disease_number; 0 .. DISEASES)
        {
            Disease disease = disease_data(disease_number);
            debug
            {
                writefln("Disease #%s: \"%s\"", disease_number, disease.name);
            }
            foreach (int symptom_number; 0 .. symptoms_count[disease_number])
            {
                Symptom symptom = symptom_data(disease_number, symptom_number);
                if
                (
                    symptom.number == symptom_to_ask_for
                    && symptoms_left[disease_number] > 0
                )
                {
                    symptoms_left[disease_number] = symptoms_left[disease_number] - 1;
                    current_prob = prob[disease_number];
                    double pe =
                        current_prob * symptom.pro_prob
                        + (1 - current_prob) * symptom.con_prob;
                    if (answer_value > 0)
                    {
                        prob[disease_number] =
                            current_prob
                            * (1 + (symptom.pro_prob / pe - 1) * to!double(answer_value)
                                / MAX_ANSWER);
                    }
                    else
                    {
                        prob[disease_number] =
                            current_prob
                            * (1
                                + (symptom.pro_prob - (1 - symptom.pro_prob) * pe / (1 - pe))
                                * to!double(answer_value) / MAX_ANSWER);
                    }
                    if (prob[disease_number] == to!int(prob[disease_number]))
                    {
                        symptoms_left[disease_number] = 0;
                    }
                }
            }
        }

        // Find new min and max rule values;

        double current_min_prob = 0.0;
        foreach (int disease_number; 0 .. DISEASES)
        {
            current_prob = prob[disease_number];
            double a1 = 1;
            double a2 = 1;
            double a3 = 1;
            double a4 = 1;
            Disease disease = disease_data(disease_number);
            foreach (int symptom_number; 0 .. symptoms_count[disease_number])
            {
                Symptom symptom = symptom_data(disease_number, symptom_number);
                if (!asked[symptom.number] && symptoms_left[disease_number] > 0)
                {
                    if (symptom.con_prob > symptom.pro_prob)
                    {
                        symptom.pro_prob = 1 - symptom.pro_prob;
                        symptom.con_prob = 1 - symptom.con_prob;
                    }
                    value[symptom.number] =
                        value[symptom.number]
                        + current_prob * symptom.pro_prob
                            / (
                                current_prob * symptom.pro_prob
                                + (1 - current_prob) * symptom.con_prob
                            )
                        - current_prob * (1 - symptom.pro_prob)
                            / (
                                current_prob * (1 - symptom.pro_prob)
                                + (1 - current_prob) * (1 - symptom.con_prob)
                            );
                    a1 = a1 * symptom.pro_prob;
                    a2 = a2 * symptom.con_prob;
                    a3 = a3 * (1 - symptom.pro_prob);
                    a4 = a4 * (1 - symptom.con_prob);
                }
            }
            max_prob[disease_number] =
                current_prob * a1 / (current_prob * a1 + (1 - current_prob) * a2);
            min_prob[disease_number] =
                current_prob * a3 / (current_prob * a3 + (1 - current_prob) * a4);
            if (max_prob[disease_number] < disease.prob)
            {
                symptoms_left[disease_number] = 0;
            }
            if (min_prob[disease_number] > current_min_prob)
            {
                hypothesis = disease_number;
                current_min_prob = min_prob[disease_number];
                debug
                {
                    Disease the_disease = disease_data(hypothesis);
                    writefln
                    (
                        "Hypothesis: %s (#%s), minimum probability: %s",
                        the_disease.name,
                        hypothesis,
                        current_min_prob
                    );
                }
            }
        }

        // Search for a clearly possible hypothesis;

        for (int disease = 0; disease < DISEASES; disease++)
        {
            if (min_prob[hypothesis] <= max_prob[disease] && disease != hypothesis)
            {
                current_min_prob = 0;
            }
        }
        if (current_min_prob != 0)
        {
            break;
        }
    }

    Disease disease = disease_data(hypothesis);
    par.whole
    (
        format
        (
            "El resultado más probable es %s con probabilidad %s.",
            disease.name,
            prob[hypothesis]
        )
    );
}

/// Print title, version and credits.

void print_credits()
{
    par.whole(TITLE);
    par.whole(format("Versión %s", VERSION));
    par.cr();
    par.whole("(C) 1985, Chris Naylor: en Sinclair BASIC.");
    par.whole("(C) 1988, 1989, Marcos Cruz (programandala.net): en SuperBASIC.");
    par.whole("(C) 2023, 2024, Marcos Cruz (programandala.net): en Odin.");
    par.whole("(C) 2025, Marcos Cruz (programandala.net): en V.");
    par.whole("(C) 2025, Marcos Cruz (programandala.net): en D.");
    par.cr();
}

/// Main loop.

void main()
{
    init();
    while (true)
    {
        terminal.clear_screen();
        print_credits();
        if (ready())
        {
            consult();
            press_enter();
        }
        else
        {
            break;
        }
    }
}

// data.d
//
// This file is part of Experto en enfermedades (Expert on diseases)

// Last modified 20250812T1903+0200.

/*

Copyright (C) 1985, Chris Naylor: Sinclair BASIC code included in his book
"Build Your Own Expert System" (Sigma Press, 1985).

Copyright (C) 1988, 1989, Marcos Cruz (programandala.net): SuperBASIC version
(http:///programandala.net/es.programa.sistema_experto_sobre_enfermedades.html).

Copyright (C) 2023, 2024, Marcos Cruz (programandala.net): Odin version.

Copyright (C) 2024, 2025, Marcos Cruz (programandala.net): SBASIC version.

Copyright (C) 2025, Marcos Cruz (programandala.net): V version.

Copyright (C) 2025, Marcos Cruz (programandala.net): D version.

This program is licensed under a BSD 2-Clause License
(https://opensource.org/license/bsd-2-clause/). See the <LICENSE.txt> file.

*/

// ==========================================================================

module data;

/// Symptom information: ordinal number, pro and con probability for a
/// requested disease, and an ok flag that indicates the data is available.

struct Symptom
{
    int number;
    double pro_prob;
    double con_prob;
    bool ok;
}

/// Disease information: name and probability.

struct Disease
{
    string name;
    double prob;
}

/// Return a [Disease] structure containing the name and probability of the
/// given disease.

Disease disease_data(int disease)
{
    switch (disease)
    {
        case 0:
            return Disease("resfriado común", 0.02);
        case 1:
            return Disease("rinitis alérgica", 0.01);
        case 2:
            return Disease("sinusitis", 0.01);
        case 3:
            return Disease("faringitis", 0.02);
        case 4:
            return Disease("amigdalitis", 0.001);
        case 5:
            return Disease("gripe", 0.01);
        case 6:
            return Disease("laringitis", 0.01);
        case 7:
            return Disease("tumor de laringe", 0.00004);
        case 8:
            return Disease("bronquitis aguda", 0.005);
        case 9:
            return Disease("bronquitis crónica", 0.005);
        case 10:
            return Disease("asma", 0.02);
        case 11:
            return Disease("enfisema pulmonar", 0.01);
        case 12:
            return Disease("neumonía", 0.003);
        case 13:
            return Disease("pleuresia", 0.001);
        case 14:
            return Disease("neumotórax", 0.0002);
        case 15:
            return Disease("bronquiectasia", 0.00001);
        case 16:
            return Disease("abceso pulmonar", 0.00001);
        case 17:
            return Disease("neumoconiosis", 0.001);
        case 18:
            return Disease("cáncer de pulmón", 0.001);
        case 19:
            return Disease("fibrosis intersticial", 0.00001);
        case 20:
            return Disease("edema pulmonar", 0.001);
        case 21:
            return Disease("gastritis", 0.01);
        case 22:
            return Disease("hernia de hiato", 0.001);
        case 23:
            return Disease("úlcera duodenal", 0.01);
        case 24:
            return Disease("úlcera gástrica", 0.01);
        case 25:
            return Disease("diverticulitis intestinal", 0.001);
        case 26:
            return Disease("enterocolitis", 0.0001);
        case 27:
            return Disease("enfermedad de Crohn", 0.0001);
        case 28:
            return Disease("oclusión intestinal", 0.00001);
        case 29:
            return Disease("apendicitis", 0.001);
        case 30:
            return Disease("intoxicación alimentaria", 0.001);
        case 31:
            return Disease("gastroenteritis", 0.01);
        case 32:
            return Disease("litiasis renal", 0.001);
        case 33:
            return Disease("pielonefritis aguda", 0.001);
        case 34:
            return Disease("litiasis biliar", 0.01);
        case 35:
            return Disease("colecistitis", 0.001);
        case 36:
            return Disease("herpes", 0.001);
        case 37:
            return Disease("trombloflebitis", 0.0005);
        case 38:
            return Disease("artritis reumatoide", 0.001);
        case 39:
            return Disease("insuficiencia cardiaca", 0.001);
        case 40:
            return Disease("ansiedad", 0.01);
        case 41:
            return Disease("depresión", 0.01);
        case 42:
            return Disease("trombosis coronaria", 0.01);
        case 43:
            return Disease("angina de pecho", 0.01);
        case 44:
            return Disease("embolia pulmonar", 0.0001);
        case 45:
            return Disease("apoplegía", 0.001);
        case 46:
            return Disease("ataque isquémico transitorio", 0.001);
        case 47:
            return Disease("tuberculosis", 0.0001);
        case 48:
            return Disease("hemorroides", 0.01);
        case 49:
            return Disease("hipotiroidismo", 0.001);
        case 50:
            return Disease("colon irritable", 0.0007);
        case 51:
            return Disease("cáncer intestinal", 0.001);
        case 52:
            return Disease("colitis ulcerosa", 0.0004);
        case 53:
            return Disease("enfermedad de Meniere", 0.0005);
        case 54:
            return Disease("espondilosis cervical", 0.006);
        case 55:
            return Disease("hemorragia subdural", 0.000001);
        case 56:
            return Disease("tumor cerebral", 0.000001);
        case 57:
            return Disease("meningitis", 0.000001);
        case 58:
            return Disease("hemorragia subaracnoidea", 0.00001);
        case 59:
            return Disease("glaucoma agudo", 0.01);
        case 60:
            return Disease("arteritis de la temporal", 0.001);
        case 61:
            return Disease("dispepsia", 0.1);
        case 62:
            return Disease("bloqueo cardiaco", 0.0003);
        case 63:
            return Disease("anemia perniciosa", 0.0004);
        case 64:
            return Disease("jaqueca", 0.1);
        case 65:
            return Disease("hipertensión esencial", 0.15);
        case 66:
            return Disease("eccema", 0.03);
        case 67:
            return Disease("urticaria", 0.03);
        case 68:
            return Disease("sarna", 0.001);
        case 69:
            return Disease("sarampión", 0.02);
        case 70:
            return Disease("rubeola", 0.01);
        case 71:
            return Disease("varicela", 0.001);
        case 72:
            return Disease("psoriasis", 0.02);
        case 73:
            return Disease("pitiriasis rubra", 0.01);
        case 74:
            return Disease("acné rosáceo", 0.01);
        case 75:
            return Disease("tirotoxicosis", 0.001);
        case 76:
            return Disease("diabetes mellitus", 0.01);
        case 77:
            return Disease("cáncer de estómago", 0.0003);
        case 78:
            return Disease("fibrilación auricular", 0.001);
        case 79:
            return Disease("enfermedad de Hodgkin", 0.0001);
        case 80:
            return Disease("fiebre glandular", 0.001);
        case 81:
            return Disease("linfoma", 0.0001);
        case 82:
            return Disease("paperas", 0.01);
        case 83:
            return Disease("parálisis facial", 0.0003);
        case 84:
            return Disease("enfermedad de Parkinson", 0.001);
        case 85:
            return Disease("artritis reumatoide", 0.01);
        case 86:
            return Disease("cistitis", 0.01);
        case 87:
            return Disease("tumor renal", 0.001);
        case 88:
            return Disease("tumor en la vejiga", 0.0004);
        case 89:
            return Disease("iritis", 0.0005);
        case 90:
            return Disease("hepatitis aguda", 0.001);
        default:
            return Disease("", 0.0);
    }
}

/// Return a [Symptom] structure containing the details about the given disease
/// and symptom.

Symptom symptom_data(int disease, int disease_symptom)
{
    switch (disease)
    {
        case 0:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(0, 0.9, 0.05, true);
                case 1:
                    return Symptom(1, 0.8, 0.02, true);
                case 2:
                    return Symptom(2, 0.8, 0.02, true);
                case 3:
                    return Symptom(4, 0.6, 0.01, true);
                case 4:
                    return Symptom(5, 1.0, 0.01, true);
                case 5:
                    return Symptom(6, 0.2, 0.01, true);
                case 6:
                    return Symptom(7, 0.5, 0.01, true);
                case 7:
                    return Symptom(14, 0.8, 0.01, true);
                case 8:
                    return Symptom(33, 0.0, 0.01, true);
                default:
                    break;
            }
            break;
        case 1:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(0, 1.0, 0.01, true);
                case 1:
                    return Symptom(1, 1.0, 0.01, true);
                case 2:
                    return Symptom(5, 0.9, 0.01, true);
                case 3:
                    return Symptom(9, 0.7, 0.01, true);
                case 4:
                    return Symptom(10, 0.7, 0.01, true);
                case 5:
                    return Symptom(11, 0.6, 0.01, true);
                case 6:
                    return Symptom(19, 0.9, 0.01, true);
                default:
                    break;
            }
            break;
        case 2:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(1, 0.5, 0.01, true);
                case 1:
                    return Symptom(5, 0.5, 0.01, true);
                case 2:
                    return Symptom(6, 0.8, 0.01, true);
                case 3:
                    return Symptom(12, 0.9, 0.01, true);
                case 4:
                    return Symptom(13, 0.8, 0.01, true);
                case 5:
                    return Symptom(14, 0.8, 0.01, true);
                case 6:
                    return Symptom(21, 0.5, 0.01, true);
                case 7:
                    return Symptom(62, 0.9, 0.01, true);
                default:
                    break;
            }
            break;
        case 3:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(2, 1.0, 0.01, true);
                case 1:
                    return Symptom(7, 0.5, 0.01, true);
                case 2:
                    return Symptom(10, 0.9, 0.01, true);
                case 3:
                    return Symptom(15, 0.9, 0.01, true);
                case 4:
                    return Symptom(36, 0.8, 0.3, true);
                case 5:
                    return Symptom(63, 0.4, 0.01, true);
                default:
                    break;
            }
            break;
        case 4:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(2, 1.0, 0.01, true);
                case 1:
                    return Symptom(6, 0.9, 0.01, true);
                case 2:
                    return Symptom(7, 0.9, 0.01, true);
                case 3:
                    return Symptom(14, 1.0, 0.01, true);
                case 4:
                    return Symptom(15, 0.7, 0.01, true);
                case 5:
                    return Symptom(18, 0.0, 0.5, true);
                case 6:
                    return Symptom(33, 0.0, 0.01, true);
                case 7:
                    return Symptom(63, 0.8, 0.01, true);
                default:
                    break;
            }
            break;
        case 5:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(0, 0.9, 0.01, true);
                case 1:
                    return Symptom(2, 0.9, 0.01, true);
                case 2:
                    return Symptom(5, 0.5, 0.01, true);
                case 3:
                    return Symptom(6, 0.7, 0.01, true);
                case 4:
                    return Symptom(7, 1.0, 0.01, true);
                case 5:
                    return Symptom(14, 1.0, 0.01, true);
                case 6:
                    return Symptom(16, 0.8, 0.01, true);
                case 7:
                    return Symptom(17, 0.6, 0.01, true);
                case 8:
                    return Symptom(33, 0.0, 0.01, true);
                default:
                    break;
            }
            break;
        case 6:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(3, 1.0, 0.01, true);
                case 1:
                    return Symptom(4, 0.9, 0.01, true);
                case 2:
                    return Symptom(7, 0.6, 0.01, true);
                case 3:
                    return Symptom(14, 0.05, 0.01, true);
                case 4:
                    return Symptom(15, 0.7, 0.01, true);
                case 5:
                    return Symptom(36, 0.8, 0.3, true);
                case 6:
                    return Symptom(20, 0.1, 0.01, true);
                default:
                    break;
            }
            break;
        case 7:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(3, 1.0, 0.01, true);
                case 1:
                    return Symptom(33, 0.99, 0.01, true);
                case 2:
                    return Symptom(36, 0.8, 0.3, true);
                default:
                    break;
            }
            break;
        case 8:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(4, 1.0, 0.01, true);
                case 1:
                    return Symptom(7, 1.0, 0.01, true);
                case 2:
                    return Symptom(11, 1.0, 0.01, true);
                case 3:
                    return Symptom(14, 1.0, 0.01, true);
                case 4:
                    return Symptom(17, 0.5, 0.01, true);
                case 5:
                    return Symptom(20, 1.0, 0.01, true);
                case 6:
                    return Symptom(21, 0.9, 0.01, true);
                case 7:
                    return Symptom(30, 0.9, 0.01, true);
                case 8:
                    return Symptom(33, 0.0, 0.01, true);
                default:
                    break;
            }
            break;
        case 9:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(4, 1.0, 0.01, true);
                case 1:
                    return Symptom(11, 0.9, 0.01, true);
                case 2:
                    return Symptom(13, 0.5, 0.01, true);
                case 3:
                    return Symptom(20, 1.0, 0.01, true);
                case 4:
                    return Symptom(21, 0.8, 0.01, true);
                case 5:
                    return Symptom(33, 1.0, 0.01, true);
                case 6:
                    return Symptom(35, 0.9, 0.01, true);
                case 7:
                    return Symptom(36, 0.8, 0.3, true);
                default:
                    break;
            }
            break;
        case 10:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(11, 0.8, 0.01, true);
                case 1:
                    return Symptom(21, 1.0, 0.01, true);
                case 2:
                    return Symptom(22, 0.5, 0.01, true);
                case 3:
                    return Symptom(23, 0.5, 0.01, true);
                case 4:
                    return Symptom(24, 0.5, 0.01, true);
                case 5:
                    return Symptom(25, 0.5, 0.01, true);
                case 6:
                    return Symptom(30, 0.8, 0.01, true);
                default:
                    break;
            }
            break;
        case 11:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(4, 0.6, 0.01, true);
                case 1:
                    return Symptom(11, 0.6, 0.01, true);
                case 2:
                    return Symptom(20, 0.6, 0.01, true);
                case 3:
                    return Symptom(21, 1.0, 0.01, true);
                case 4:
                    return Symptom(25, 0.8, 0.01, true);
                case 5:
                    return Symptom(36, 0.8, 0.3, true);
                default:
                    break;
            }
            break;
        case 12:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(7, 1.0, 0.01, true);
                case 1:
                    return Symptom(14, 1.0, 0.01, true);
                case 2:
                    return Symptom(16, 0.9, 0.01, true);
                case 3:
                    return Symptom(17, 0.8, 0.01, true);
                case 4:
                    return Symptom(21, 1.0, 0.01, true);
                case 5:
                    return Symptom(22, 0.5, 0.01, true);
                case 6:
                    return Symptom(25, 0.5, 0.01, true);
                case 7:
                    return Symptom(26, 0.2, 0.01, true);
                case 8:
                    return Symptom(27, 0.1, 0.01, true);
                case 9:
                    return Symptom(28, 0.02, 0.01, true);
                case 10:
                    return Symptom(30, 0.9, 0.01, true);
                case 11:
                    return Symptom(31, 0.5, 0.005, true);
                case 12:
                    return Symptom(35, 0.1, 0.9, true);
                default:
                    break;
            }
            break;
        case 13:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(4, 0.8, 0.01, true);
                case 1:
                    return Symptom(7, 0.9, 0.01, true);
                case 2:
                    return Symptom(14, 1.0, 0.01, true);
                case 3:
                    return Symptom(21, 0.5, 0.01, true);
                case 4:
                    return Symptom(30, 0.8, 0.01, true);
                case 5:
                    return Symptom(31, 0.8, 0.01, true);
                case 6:
                    return Symptom(33, 0.0, 0.01, true);
                default:
                    break;
            }
            break;
        case 14:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(17, 0.8, 0.01, true);
                case 1:
                    return Symptom(21, 0.8, 0.01, true);
                case 2:
                    return Symptom(31, 0.8, 0.005, true);
                default:
                    break;
            }
            break;
        case 15:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(4, 1.0, 0.01, true);
                case 1:
                    return Symptom(13, 0.5, 0.01, true);
                case 2:
                    return Symptom(20, 1.0, 0.01, true);
                case 3:
                    return Symptom(26, 0.5, 0.01, true);
                default:
                    break;
            }
            break;
        case 16:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(17, 0.5, 0.01, true);
                case 1:
                    return Symptom(20, 0.5, 0.01, true);
                case 2:
                    return Symptom(26, 0.5, 0.01, true);
                case 3:
                    return Symptom(32, 0.9, 0.01, true);
                default:
                    break;
            }
            break;
        case 17:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(8, 1.0, 0.01, true);
                case 1:
                    return Symptom(20, 0.8, 0.01, true);
                case 2:
                    return Symptom(21, 1.0, 0.01, true);
                case 3:
                    return Symptom(35, 1.0, 0.01, true);
                default:
                    break;
            }
            break;
        case 18:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(4, 1.0, 0.01, true);
                case 1:
                    return Symptom(11, 0.5, 0.01, true);
                case 2:
                    return Symptom(17, 0.8, 0.01, true);
                case 3:
                    return Symptom(20, 0.8, 0.01, true);
                case 4:
                    return Symptom(21, 0.5, 0.01, true);
                case 5:
                    return Symptom(26, 0.5, 0.01, true);
                case 6:
                    return Symptom(36, 0.99, 0.3, true);
                default:
                    break;
            }
            break;
        case 19:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(20, 0.6, 0.01, true);
                case 1:
                    return Symptom(21, 0.8, 0.01, true);
                case 2:
                    return Symptom(34, 0.8, 0.01, true);
                default:
                    break;
            }
            break;
        case 20:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(11, 0.8, 0.01, true);
                case 1:
                    return Symptom(21, 0.9, 0.01, true);
                case 2:
                    return Symptom(24, 0.9, 0.01, true);
                case 3:
                    return Symptom(25, 0.5, 0.01, true);
                case 4:
                    return Symptom(26, 0.5, 0.01, true);
                case 5:
                    return Symptom(29, 0.5, 0.01, true);
                default:
                    break;
            }
            break;
        case 21:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(7, 0.4, 0.01, true);
                case 1:
                    return Symptom(36, 0.9, 0.5, true);
                case 2:
                    return Symptom(40, 0.01, 0.8, true);
                case 3:
                    return Symptom(42, 0.8, 0.01, true);
                case 4:
                    return Symptom(41, 0.5, 0.01, true);
                default:
                    break;
            }
            break;
        case 22:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(15, 0.9, 0.01, true);
                case 1:
                    return Symptom(17, 0.9, 0.01, true);
                case 2:
                    return Symptom(31, 0.5, 0.005, true);
                case 3:
                    return Symptom(40, 0.8, 0.01, true);
                case 4:
                    return Symptom(41, 0.8, 0.005, true);
                case 5:
                    return Symptom(56, 0.9, 0.01, true);
                default:
                    break;
            }
            break;
        case 23:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(36, 0.8, 0.2, true);
                case 1:
                    return Symptom(40, 0.8, 0.01, true);
                case 2:
                    return Symptom(41, 0.99, 0.005, true);
                case 3:
                    return Symptom(56, 0.7, 0.01, true);
                default:
                    break;
            }
            break;
        case 24:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(19, 0.8, 0.01, true);
                case 1:
                    return Symptom(40, 0.7, 0.01, true);
                case 2:
                    return Symptom(41, 0.9, 0.005, true);
                case 3:
                    return Symptom(45, 0.5, 0.01, true);
                case 4:
                    return Symptom(55, 0.9, 0.01, true);
                case 5:
                    return Symptom(61, 0.0001, 0.01, true);
                default:
                    break;
            }
            break;
        case 25:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(7, 0.5, 0.01, true);
                case 1:
                    return Symptom(40, 0.5, 0.01, true);
                case 2:
                    return Symptom(41, 0.6, 0.005, true);
                case 3:
                    return Symptom(42, 0.5, 0.01, true);
                case 4:
                    return Symptom(55, 0.8, 0.01, true);
                default:
                    break;
            }
            break;
        case 26:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(7, 0.3, 0.01, true);
                case 1:
                    return Symptom(22, 0.3, 0.01, true);
                case 2:
                    return Symptom(40, 0.3, 0.01, true);
                case 3:
                    return Symptom(41, 0.9, 0.005, true);
                case 4:
                    return Symptom(42, 0.7, 0.01, true);
                default:
                    break;
            }
            break;
        case 27:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(7, 0.7, 0.01, true);
                case 1:
                    return Symptom(14, 0.9, 0.01, true);
                case 2:
                    return Symptom(41, 0.9, 0.005, true);
                case 3:
                    return Symptom(42, 0.9, 0.01, true);
                case 4:
                    return Symptom(61, 0.00001, 0.01, true);
                default:
                    break;
            }
            break;
        case 28:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(40, 0.5, 0.01, true);
                case 1:
                    return Symptom(41, 0.9, 0.005, true);
                case 2:
                    return Symptom(42, 0.8, 0.01, true);
                default:
                    break;
            }
            break;
        case 29:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(7, 0.8, 0.01, true);
                case 1:
                    return Symptom(33, 0.1, 0.9, true);
                case 2:
                    return Symptom(40, 0.8, 0.01, true);
                case 3:
                    return Symptom(41, 0.9, 0.005, true);
                case 4:
                    return Symptom(43, 0.0, 0.5, true);
                default:
                    break;
            }
            break;
        case 30:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(6, 0.8, 0.01, true);
                case 1:
                    return Symptom(40, 0.9, 0.01, true);
                case 2:
                    return Symptom(41, 0.5, 0.005, true);
                case 3:
                    return Symptom(42, 0.9, 0.01, true);
                default:
                    break;
            }
            break;
        case 31:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(7, 0.5, 0.01, true);
                case 1:
                    return Symptom(40, 0.8, 0.01, true);
                case 2:
                    return Symptom(41, 0.7, 0.005, true);
                case 3:
                    return Symptom(42, 0.9, 0.01, true);
                default:
                    break;
            }
            break;
        case 32:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(41, 0.7, 0.005, true);
                default:
                    break;
            }
            break;
        case 33:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(7, 0.8, 0.01, true);
                case 1:
                    return Symptom(40, 0.7, 0.01, true);
                case 2:
                    return Symptom(41, 0.9, 0.005, true);
                case 3:
                    return Symptom(66, 0.9, 0.01, true);
                default:
                    break;
            }
            break;
        case 34:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(40, 0.5, 0.01, true);
                case 1:
                    return Symptom(41, 0.5, 0.005, true);
                case 2:
                    return Symptom(56, 0.9, 0.01, true);
                default:
                    break;
            }
            break;
        case 35:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(7, 0.9, 0.01, true);
                case 1:
                    return Symptom(40, 0.8, 0.01, true);
                case 2:
                    return Symptom(41, 0.8, 0.005, true);
                case 3:
                    return Symptom(44, 0.8, 0.001, true);
                default:
                    break;
            }
            break;
        case 36:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(1, 0.6, 0.01, true);
                case 1:
                    return Symptom(7, 0.5, 0.01, true);
                case 2:
                    return Symptom(13, 0.8, 0.01, true);
                case 3:
                    return Symptom(17, 0.5, 0.01, true);
                case 4:
                    return Symptom(58, 0.9, 0.01, true);
                case 5:
                    return Symptom(59, 0.9, 0.01, true);
                default:
                    break;
            }
            break;
        case 37:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(39, 0.8, 0.01, true);
                default:
                    break;
            }
            break;
        case 38:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(14, 0.8, 0.01, true);
                case 1:
                    return Symptom(16, 0.8, 0.01, true);
                case 2:
                    return Symptom(39, 0.5, 0.001, true);
                default:
                    break;
            }
            break;
        case 39:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(11, 0.6, 0.01, true);
                case 1:
                    return Symptom(17, 0.5, 0.01, true);
                case 2:
                    return Symptom(21, 0.9, 0.01, true);
                case 3:
                    return Symptom(24, 0.5, 0.001, true);
                case 4:
                    return Symptom(25, 0.3, 0.001, true);
                case 5:
                    return Symptom(31, 0.3, 0.001, true);
                case 6:
                    return Symptom(35, 0.5, 0.01, true);
                case 7:
                    return Symptom(38, 0.5, 0.01, true);
                case 8:
                    return Symptom(41, 0.5, 0.01, true);
                case 9:
                    return Symptom(46, 0.9, 0.01, true);
                default:
                    break;
            }
            break;
        case 40:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(6, 0.5, 0.01, true);
                case 1:
                    return Symptom(14, 0.5, 0.01, true);
                case 2:
                    return Symptom(15, 0.3, 0.01, true);
                case 3:
                    return Symptom(21, 0.5, 0.01, true);
                case 4:
                    return Symptom(22, 0.6, 0.01, true);
                case 5:
                    return Symptom(27, 0.3, 0.01, true);
                case 6:
                    return Symptom(37, 0.5, 0.01, true);
                case 7:
                    return Symptom(38, 0.8, 0.01, true);
                case 8:
                    return Symptom(42, 0.2, 0.01, true);
                case 9:
                    return Symptom(45, 0.9, 0.01, true);
                case 10:
                    return Symptom(46, 0.6, 0.01, true);
                case 11:
                    return Symptom(47, 0.6, 0.01, true);
                case 12:
                    return Symptom(49, 0.5, 0.01, true);
                case 13:
                    return Symptom(56, 0.5, 0.01, true);
                case 14:
                    return Symptom(57, 0.5, 0.01, true);
                default:
                    break;
            }
            break;
        case 41:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(6, 0.5, 0.01, true);
                case 1:
                    return Symptom(14, 0.5, 0.01, true);
                case 2:
                    return Symptom(46, 0.5, 0.01, true);
                case 3:
                    return Symptom(48, 0.5, 0.01, true);
                case 4:
                    return Symptom(49, 0.5, 0.01, true);
                case 5:
                    return Symptom(61, 0.8, 0.01, true);
                default:
                    break;
            }
            break;
        case 42:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(14, 0.9, 0.01, true);
                case 1:
                    return Symptom(17, 0.5, 0.01, true);
                case 2:
                    return Symptom(19, 0.5, 0.01, true);
                case 3:
                    return Symptom(21, 0.5, 0.01, true);
                case 4:
                    return Symptom(22, 0.5, 0.01, true);
                case 5:
                    return Symptom(31, 0.9, 0.001, true);
                case 6:
                    return Symptom(35, 0.0, 0.2, true);
                case 7:
                    return Symptom(37, 0.5, 0.01, true);
                case 8:
                    return Symptom(40, 0.5, 0.01, true);
                default:
                    break;
            }
            break;
        case 43:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(17, 0.9, 0.01, true);
                case 1:
                    return Symptom(19, 0.9, 0.01, true);
                case 2:
                    return Symptom(21, 0.5, 0.01, true);
                case 3:
                    return Symptom(22, 0.5, 0.01, true);
                case 4:
                    return Symptom(31, 1.0, 0.001, true);
                case 5:
                    return Symptom(35, 0.9, 0.01, true);
                case 6:
                    return Symptom(36, 0.8, 0.3, true);
                case 7:
                    return Symptom(37, 0.5, 0.01, true);
                default:
                    break;
            }
            break;
        case 44:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(17, 0.7, 0.01, true);
                case 1:
                    return Symptom(20, 0.6, 0.01, true);
                case 2:
                    return Symptom(21, 1.0, 0.01, true);
                case 3:
                    return Symptom(24, 0.5, 0.001, true);
                case 4:
                    return Symptom(25, 0.4, 0.001, true);
                case 5:
                    return Symptom(26, 0.5, 0.001, true);
                default:
                    break;
            }
            break;
        case 45:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(27, 0.8, 0.01, true);
                case 1:
                    return Symptom(37, 0.7, 0.01, true);
                case 2:
                    return Symptom(50, 0.8, 0.001, true);
                case 3:
                    return Symptom(57, 0.9, 0.01, true);
                case 4:
                    return Symptom(60, 0.9, 0.01, true);
                default:
                    break;
            }
            break;
        case 46:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(19, 0.5, 0.01, true);
                case 1:
                    return Symptom(27, 0.8, 0.01, true);
                case 2:
                    return Symptom(33, 0.0, 0.01, true);
                case 3:
                    return Symptom(37, 0.7, 0.01, true);
                case 4:
                    return Symptom(50, 0.8, 0.001, true);
                case 5:
                    return Symptom(57, 0.9, 0.01, true);
                case 6:
                    return Symptom(60, 0.9, 0.01, true);
                default:
                    break;
            }
            break;
        case 47:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(4, 0.5, 0.01, true);
                case 1:
                    return Symptom(6, 0.5, 0.01, true);
                case 2:
                    return Symptom(7, 0.5, 0.01, true);
                case 3:
                    return Symptom(11, 0.5, 0.01, true);
                case 4:
                    return Symptom(14, 0.5, 0.01, true);
                case 5:
                    return Symptom(17, 0.5, 0.01, true);
                case 6:
                    return Symptom(21, 0.5, 0.01, true);
                case 7:
                    return Symptom(22, 0.5, 0.01, true);
                case 8:
                    return Symptom(26, 0.5, 0.001, true);
                case 9:
                    return Symptom(29, 0.5, 0.01, true);
                case 10:
                    return Symptom(61, 0.0001, 0.01, true);
                default:
                    break;
            }
            break;
        case 48:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(48, 0.8, 0.01, true);
                case 1:
                    return Symptom(51, 0.9, 0.001, true);
                case 2:
                    return Symptom(55, 0.9, 0.01, true);
                case 3:
                    return Symptom(58, 0.5, 0.01, true);
                default:
                    break;
            }
            break;
        case 49:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(3, 0.5, 0.01, true);
                case 1:
                    return Symptom(16, 0.5, 0.01, true);
                case 2:
                    return Symptom(22, 0.001, 0.01, true);
                case 3:
                    return Symptom(23, 0.0, 0.01, true);
                case 4:
                    return Symptom(38, 0.001, 0.01, true);
                case 5:
                    return Symptom(42, 0.0, 0.01, true);
                case 6:
                    return Symptom(45, 0.001, 0.01, true);
                case 7:
                    return Symptom(47, 0.001, 0.01, true);
                case 8:
                    return Symptom(48, 0.8, 0.01, true);
                case 9:
                    return Symptom(61, 0.9, 0.05, true);
                default:
                    break;
            }
            break;
        case 50:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(40, 0.3, 0.01, true);
                case 1:
                    return Symptom(41, 0.8, 0.001, true);
                case 2:
                    return Symptom(42, 0.5, 0.01, true);
                case 3:
                    return Symptom(48, 0.5, 0.01, true);
                case 4:
                    return Symptom(55, 0.5, 0.01, true);
                case 5:
                    return Symptom(56, 0.9, 0.01, true);
                default:
                    break;
            }
            break;
        case 51:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(41, 0.5, 0.005, true);
                case 1:
                    return Symptom(42, 0.9, 0.01, true);
                case 2:
                    return Symptom(48, 0.9, 0.01, true);
                case 3:
                    return Symptom(51, 0.5, 0.001, true);
                case 4:
                    return Symptom(55, 0.9, 0.01, true);
                case 5:
                    return Symptom(61, 0.0001, 0.01, true);
                default:
                    break;
            }
            break;
        case 52:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(7, 0.5, 0.01, true);
                case 1:
                    return Symptom(22, 0.5, 0.01, true);
                case 2:
                    return Symptom(33, 0.4, 0.01, true);
                case 3:
                    return Symptom(40, 0.5, 0.01, true);
                case 4:
                    return Symptom(41, 0.8, 0.005, true);
                case 5:
                    return Symptom(42, 0.8, 0.01, true);
                case 6:
                    return Symptom(51, 0.6, 0.001, true);
                case 7:
                    return Symptom(55, 0.9, 0.01, true);
                default:
                    break;
            }
            break;
        case 53:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(19, 0.9, 0.01, true);
                case 1:
                    return Symptom(33, 0.5, 0.01, true);
                case 2:
                    return Symptom(37, 0.9, 0.001, true);
                case 3:
                    return Symptom(40, 0.8, 0.01, true);
                default:
                    break;
            }
            break;
        case 54:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(6, 0.5, 0.01, true);
                case 1:
                    return Symptom(37, 0.5, 0.01, true);
                case 2:
                    return Symptom(53, 0.9, 0.01, true);
                case 3:
                    return Symptom(57, 0.9, 0.01, true);
                case 4:
                    return Symptom(60, 0.5, 0.01, true);
                default:
                    break;
            }
            break;
        case 55:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(6, 0.9, 0.01, true);
                case 1:
                    return Symptom(19, 0.5, 0.01, true);
                case 2:
                    return Symptom(27, 0.9, 0.001, true);
                case 3:
                    return Symptom(33, 0.5, 0.01, true);
                case 4:
                    return Symptom(37, 0.9, 0.01, true);
                case 5:
                    return Symptom(40, 0.9, 0.01, true);
                case 6:
                    return Symptom(54, 0.99, 0.001, true);
                default:
                    break;
            }
            break;
        case 56:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(6, 0.9, 0.01, true);
                case 1:
                    return Symptom(33, 0.5, 0.01, true);
                case 2:
                    return Symptom(37, 0.8, 0.01, true);
                case 3:
                    return Symptom(40, 0.9, 0.01, true);
                case 4:
                    return Symptom(49, 0.8, 0.01, true);
                default:
                    break;
            }
            break;
        case 57:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(1, 0.9, 0.01, true);
                case 1:
                    return Symptom(6, 0.9, 0.01, true);
                case 2:
                    return Symptom(7, 0.9, 0.01, true);
                case 3:
                    return Symptom(27, 0.7, 0.01, true);
                case 4:
                    return Symptom(40, 0.9, 0.01, true);
                case 5:
                    return Symptom(53, 0.9, 0.01, true);
                case 6:
                    return Symptom(59, 0.5, 0.01, true);
                default:
                    break;
            }
            break;
        case 58:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(1, 0.8, 0.01, true);
                case 1:
                    return Symptom(6, 0.99, 0.01, true);
                case 2:
                    return Symptom(27, 0.7, 0.01, true);
                case 3:
                    return Symptom(37, 0.7, 0.01, true);
                case 4:
                    return Symptom(40, 0.8, 0.01, true);
                case 5:
                    return Symptom(53, 0.9, 0.01, true);
                default:
                    break;
            }
            break;
        case 59:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(1, 0.9, 0.01, true);
                case 1:
                    return Symptom(6, 0.9, 0.01, true);
                case 2:
                    return Symptom(19, 0.8, 0.01, true);
                case 3:
                    return Symptom(33, 0.8, 0.01, true);
                case 4:
                    return Symptom(40, 0.7, 0.01, true);
                case 5:
                    return Symptom(62, 0.9, 0.01, true);
                case 6:
                    return Symptom(67, 0.9, 0.01, true);
                default:
                    break;
            }
            break;
        case 60:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(6, 0.9, 0.01, true);
                case 1:
                    return Symptom(7, 0.7, 0.01, true);
                case 2:
                    return Symptom(16, 0.7, 0.01, true);
                case 3:
                    return Symptom(22, 0.8, 0.01, true);
                case 4:
                    return Symptom(62, 0.99, 0.01, true);
                default:
                    break;
            }
            break;
        case 61:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(6, 0.7, 0.01, true);
                case 1:
                    return Symptom(19, 0.9, 0.01, true);
                case 2:
                    return Symptom(40, 0.7, 0.01, true);
                case 3:
                    return Symptom(41, 0.7, 0.01, true);
                case 4:
                    return Symptom(56, 0.7, 0.01, true);
                case 5:
                    return Symptom(61, 0.001, 0.01, true);
                default:
                    break;
            }
            break;
        case 62:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(17, 0.6, 0.01, true);
                case 1:
                    return Symptom(21, 0.5, 0.01, true);
                case 2:
                    return Symptom(38, 0.6, 0.01, true);
                case 3:
                    return Symptom(57, 0.8, 0.01, true);
                default:
                    break;
            }
            break;
        case 63:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(21, 0.9, 0.01, true);
                case 1:
                    return Symptom(27, 0.4, 0.01, true);
                case 2:
                    return Symptom(35, 0.9, 0.01, true);
                case 3:
                    return Symptom(38, 0.9, 0.01, true);
                case 4:
                    return Symptom(41, 0.5, 0.01, true);
                case 5:
                    return Symptom(44, 0.5, 0.01, true);
                case 6:
                    return Symptom(49, 0.5, 0.01, true);
                case 7:
                    return Symptom(57, 0.9, 0.01, true);
                default:
                    break;
            }
            break;
        case 64:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(1, 0.9, 0.01, true);
                case 1:
                    return Symptom(6, 1.0, 0.01, true);
                case 2:
                    return Symptom(14, 0.9, 0.01, true);
                case 3:
                    return Symptom(19, 0.9, 0.01, true);
                case 4:
                    return Symptom(33, 0.9, 0.01, true);
                case 5:
                    return Symptom(40, 0.9, 0.01, true);
                case 6:
                    return Symptom(42, 0.5, 0.01, true);
                case 7:
                    return Symptom(62, 0.99, 0.01, true);
                default:
                    break;
            }
            break;
        case 65:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(6, 0.5, 0.01, true);
                case 1:
                    return Symptom(14, 0.9, 0.01, true);
                case 2:
                    return Symptom(33, 0.9, 0.01, true);
                case 3:
                    return Symptom(38, 0.5, 0.01, true);
                default:
                    break;
            }
            break;
        case 66:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(58, 0.9, 0.01, true);
                case 1:
                    return Symptom(59, 0.1, 0.01, true);
                default:
                    break;
            }
            break;
        case 67:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(45, 0.5, 0.01, true);
                case 1:
                    return Symptom(58, 0.9, 0.01, true);
                case 2:
                    return Symptom(59, 1.0, 0.01, true);
                default:
                    break;
            }
            break;
        case 68:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(58, 1.0, 0.01, true);
                case 1:
                    return Symptom(59, 1.0, 0.01, true);
                default:
                    break;
            }
            break;
        case 69:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(1, 0.9, 0.01, true);
                case 1:
                    return Symptom(4, 0.9, 0.01, true);
                case 2:
                    return Symptom(5, 0.9, 0.01, true);
                case 3:
                    return Symptom(6, 0.5, 0.01, true);
                case 4:
                    return Symptom(7, 1.0, 0.01, true);
                case 5:
                    return Symptom(10, 0.9, 0.01, true);
                case 6:
                    return Symptom(14, 1.0, 0.01, true);
                case 7:
                    return Symptom(33, 0.0, 0.01, true);
                case 8:
                    return Symptom(42, 0.5, 0.01, true);
                case 9:
                    return Symptom(59, 1.0, 0.01, true);
                default:
                    break;
            }
            break;
        case 70:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(7, 0.5, 0.01, true);
                case 1:
                    return Symptom(33, 0.0, 0.01, true);
                case 2:
                    return Symptom(53, 0.2, 0.01, true);
                case 3:
                    return Symptom(59, 0.9, 0.01, true);
                case 4:
                    return Symptom(63, 0.5, 0.01, true);
                default:
                    break;
            }
            break;
        case 71:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(6, 0.5, 0.01, true);
                case 1:
                    return Symptom(7, 0.8, 0.01, true);
                case 2:
                    return Symptom(14, 0.5, 0.01, true);
                case 3:
                    return Symptom(33, 0.0, 0.01, true);
                case 4:
                    return Symptom(58, 1.0, 0.01, true);
                case 5:
                    return Symptom(59, 1.0, 0.01, true);
                default:
                    break;
            }
            break;
        case 72:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(2, 0.5, 0.01, true);
                case 1:
                    return Symptom(45, 0.6, 0.01, true);
                case 2:
                    return Symptom(58, 0.5, 0.01, true);
                case 3:
                    return Symptom(59, 0.99, 0.01, true);
                default:
                    break;
            }
            break;
        case 73:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(33, 0.5, 0.01, true);
                case 1:
                    return Symptom(58, 0.9, 0.01, true);
                case 2:
                    return Symptom(59, 1.0, 0.01, true);
                default:
                    break;
            }
            break;
        case 74:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(1, 0.5, 0.01, true);
                case 1:
                    return Symptom(33, 0.8, 0.01, true);
                case 2:
                    return Symptom(59, 0.9, 0.01, true);
                default:
                    break;
            }
            break;
        case 75:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(1, 0.5, 0.01, true);
                case 1:
                    return Symptom(21, 0.8, 0.01, true);
                case 2:
                    return Symptom(22, 0.9, 0.01, true);
                case 3:
                    return Symptom(23, 0.9, 0.01, true);
                case 4:
                    return Symptom(38, 0.9, 0.01, true);
                case 5:
                    return Symptom(42, 0.8, 0.01, true);
                case 6:
                    return Symptom(45, 0.9, 0.01, true);
                case 7:
                    return Symptom(46, 0.8, 0.01, true);
                case 8:
                    return Symptom(47, 0.9, 0.01, true);
                case 9:
                    return Symptom(61, 0.00001, 0.01, true);
                case 10:
                    return Symptom(63, 0.3, 0.01, true);
                case 11:
                    return Symptom(67, 0.3, 0.01, true);
                default:
                    break;
            }
            break;
        case 76:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(1, 0.5, 0.01, true);
                case 1:
                    return Symptom(60, 0.5, 0.01, true);
                case 2:
                    return Symptom(61, 0.0001, 0.01, true);
                case 3:
                    return Symptom(65, 0.99, 0.01, true);
                case 4:
                    return Symptom(67, 1.0, 0.01, true);
                default:
                    break;
            }
            break;
        case 77:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(40, 0.5, 0.01, true);
                case 1:
                    return Symptom(41, 0.7, 0.005, true);
                case 2:
                    return Symptom(51, 0.6, 0.001, true);
                case 3:
                    return Symptom(55, 0.5, 0.01, true);
                case 4:
                    return Symptom(61, 0.0001, 0.01, true);
                default:
                    break;
            }
            break;
        case 78:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(19, 0.4, 0.01, true);
                case 1:
                    return Symptom(37, 0.5, 0.01, true);
                case 2:
                    return Symptom(38, 0.8, 0.01, true);
                case 3:
                    return Symptom(57, 0.5, 0.01, true);
                default:
                    break;
            }
            break;
        case 79:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(22, 0.5, 0.01, true);
                case 1:
                    return Symptom(53, 0.8, 0.01, true);
                case 2:
                    return Symptom(58, 0.7, 0.01, true);
                case 3:
                    return Symptom(62, 0.6, 0.01, true);
                case 4:
                    return Symptom(63, 0.99, 0.01, true);
                default:
                    break;
            }
            break;
        case 80:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(2, 0.9, 0.01, true);
                case 1:
                    return Symptom(6, 0.9, 0.01, true);
                case 2:
                    return Symptom(7, 0.9, 0.01, true);
                case 3:
                    return Symptom(14, 0.9, 0.01, true);
                case 4:
                    return Symptom(44, 0.5, 0.001, true);
                case 5:
                    return Symptom(53, 0.8, 0.01, true);
                case 6:
                    return Symptom(59, 0.5, 0.01, true);
                case 7:
                    return Symptom(63, 0.8, 0.01, true);
                default:
                    break;
            }
            break;
        case 81:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(7, 0.8, 0.01, true);
                case 1:
                    return Symptom(14, 0.8, 0.01, true);
                case 2:
                    return Symptom(22, 0.5, 0.01, true);
                case 3:
                    return Symptom(53, 0.8, 0.01, true);
                case 4:
                    return Symptom(58, 0.8, 0.01, true);
                case 5:
                    return Symptom(61, 0.001, 0.01, true);
                case 6:
                    return Symptom(63, 0.9, 0.01, true);
                default:
                    break;
            }
            break;
        case 82:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(2, 0.8, 0.01, true);
                case 1:
                    return Symptom(7, 0.8, 0.01, true);
                case 2:
                    return Symptom(14, 0.9, 0.01, true);
                case 3:
                    return Symptom(15, 0.7, 0.01, true);
                case 4:
                    return Symptom(53, 0.6, 0.01, true);
                case 5:
                    return Symptom(63, 0.99, 0.01, true);
                default:
                    break;
            }
            break;
        case 83:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(1, 0.9, 0.01, true);
                case 1:
                    return Symptom(50, 0.9, 0.01, true);
                case 2:
                    return Symptom(62, 0.5, 0.01, true);
                default:
                    break;
            }
            break;
        case 84:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(27, 0.2, 0.01, true);
                case 1:
                    return Symptom(33, 1.0, 0.01, true);
                case 2:
                    return Symptom(47, 0.9, 0.01, true);
                case 3:
                    return Symptom(49, 0.2, 0.01, true);
                case 4:
                    return Symptom(50, 0.8, 0.01, true);
                case 5:
                    return Symptom(52, 0.8, 0.5, true);
                default:
                    break;
            }
            break;
        case 85:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(6, 0.8, 0.01, true);
                case 1:
                    return Symptom(7, 0.8, 0.01, true);
                case 2:
                    return Symptom(14, 0.8, 0.01, true);
                case 3:
                    return Symptom(47, 0.1, 0.01, true);
                case 4:
                    return Symptom(58, 0.001, 0.01, true);
                case 5:
                    return Symptom(59, 0.5, 0.01, true);
                case 6:
                    return Symptom(63, 0.8, 0.01, true);
                default:
                    break;
            }
            break;
        case 86:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(7, 0.5, 0.01, true);
                case 1:
                    return Symptom(64, 0.9, 0.01, true);
                case 2:
                    return Symptom(65, 0.9, 0.01, true);
                case 3:
                    return Symptom(66, 0.9, 0.01, true);
                default:
                    break;
            }
            break;
        case 87:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(7, 0.6, 0.01, true);
                case 1:
                    return Symptom(40, 0.5, 0.01, true);
                case 2:
                    return Symptom(41, 0.5, 0.01, true);
                case 3:
                    return Symptom(61, 0.0001, 0.01, true);
                case 4:
                    return Symptom(64, 0.7, 0.01, true);
                default:
                    break;
            }
            break;
        case 88:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(7, 0.3, 0.01, true);
                case 1:
                    return Symptom(41, 0.5, 0.01, true);
                case 2:
                    return Symptom(64, 0.9, 0.01, true);
                case 3:
                    return Symptom(65, 0.5, 0.01, true);
                case 4:
                    return Symptom(66, 0.5, 0.01, true);
                default:
                    break;
            }
            break;
        case 89:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(1, 0.9, 0.01, true);
                case 1:
                    return Symptom(67, 0.9, 0.01, true);
                default:
                    break;
            }
            break;
        case 90:
            switch (disease_symptom)
            {
                case 0:
                    return Symptom(7, 0.8, 0.01, true);
                case 1:
                    return Symptom(14, 0.8, 0.01, true);
                case 2:
                    return Symptom(16, 0.5, 0.01, true);
                case 3:
                    return Symptom(40, 0.5, 0.01, true);
                case 4:
                    return Symptom(41, 0.5, 0.01, true);
                case 5:
                    return Symptom(44, 0.5, 0.01, true);
                default:
                    break;
            }
            break;
        default:
            break;
    }
    return Symptom(0, 0.0, 0.0, false);
}

/// Return the question about the given symptom.

string question(int symptom)
{
    switch (symptom)
    {
        case 0:
            return "¿Estornudas mucho?";
        case 1:
            return "¿Te duelen los ojos, o lagrimeas mucho?";
        case 2:
            return "¿Te duele la garganta?";
        case 3:
            return "¿Tienes ronquera o afonía?";
        case 4:
            return "¿Toses mucho?";
        case 5:
            return "¿Tienes mucosidad nasal muy fluida?";
        case 6:
            return "¿Te duele la cabeza, o sufres, en general, de dolores de cabeza?";
        case 7:
            return "¿Tienes alta temperatura (superior a 37 grados centígrados)?";
        case 8:
            return "¿Te ves obligado, por tu trabajo, "
                ~ "a pasar muchas horas respirando aire viciado o polvoriento?";
        case 9:
            return "¿Te pica la nariz?";
        case 10:
            return "¿Tienes la garganta reseca?";
        case 11:
            return "¿Respiras con dificultad y fatiga?";
        case 12:
            return "¿Tienes la nariz muy taponada?";
        case 13:
            return "¿Has tenido recientemente un resfriado u otra infección similar?";
        case 14:
            return "¿Tienes malestar general?";
        case 15:
            return "¿Tienes dificultad para tragar?";
        case 16:
            return "¿Tienes dolores musculares?";
        case 17:
            return "¿Sientes cualquier tipo de dolor en el pecho?";
        case 18:
            return "¿Te han extirpado las amigdalas?";
        case 19:
            return "¿Tus síntomas tienden a aparecer en ataques, "
                ~ "y no a estar presentes continuamente?";
        case 20:
            return "¿Tienes una tos productiva, o sea una tos en la que expulsas algo?";
        case 21:
            return "¿Respiras entrecortadamente?";
        case 22:
            return "¿Sudas mucho? (No ya cuando haces un esfuerzo, "
                ~ "sino cuando estás físicamente relajado).";
        case 23:
            return "¿Tienes la frecuencia cardiaca elevada? "
                ~ "(Normalmente debe estar entre 60 y 80 pulsaciones por minuto, "
                ~ "y algo más rápida para personas de edad superior a 70 o inferior a 20).";
        case 24:
            return "¿Sufres ataques de dificultades respiratorias "
                ~ "tan fuertes que llegan a preocuparte?";
        case 25:
            return "¿Tienes cianosis, es decir, "
                ~ " se te ha puesto la piel de un color ligeramente azulado?";
        case 26:
            return "¿Cuando toses, presentan sangre los esputos?";
        case 27:
            return "¿Estás aturdido o perplejo sobre cuanto acontece a tu alrededor?";
        case 28:
            return "¿Estás (o está el paciente) en estado delirante, "
                ~ "hablando incoherentemente y con mala coordinación muscular?";
        case 29:
            return "¿Tienes una tos seca (no productiva)?";
        case 30:
            return "¿Sientes dolor al respirar o al toser?";
        case 31:
            return "¿Has sentido en estos días un dolor muy fuerte en el pecho?";
        case 32:
            return "¿Tienes sensaciones alternantes de frío y calor?";
        case 33:
            return "¿Hace ya tiempo (seis semanas o más) "
                ~ "que presentas alguno de estos síntomas?";
        case 34:
            return "¿Tienes los dedos hipocráticos, o en «palillos de tambor»? "
                ~ "(Se llaman así cuando las cutículas casi han desaparecido, "
                ~ "y las uñas se abomban excesivamente hacia la punta).";
        case 35:
            return "¿Tienes síntomas que aparecen "
                ~ "fundamentalmente al realizar algún esfuerzo?";
        case 36:
            return "¿Fumas? responde con el número que resulta de dividir por cinco "
                ~ "el número de cigarrillos diarios. "
                ~ "El número máximo para la respuesta es 5. "
                ~ "Si no fumas, responde -5.";
        case 37:
            return "¿Tienes sensaciones de vértigo?";
        case 38:
            return "¿Tienes palpitaciones (sensación de que el corazón late más fuerte, "
                ~ "o más rápido, o menos regularmente de lo que debiera)?";
        case 39:
            return "¿Tienes algún tobillo excesivamente hinchado?";
        case 40:
            return "¿Tienes vómitos, o fuertes náuseas?";
        case 41:
            return "¿Sufres de algún tipo de dolor abdominal, o dolor localizado "
                ~ " entre las costillas inferiores y las ingles?";
        case 42:
            return "¿Padeces diarrea, o sueles tener crisis de diarrea?";
        case 43:
            return "¿Te han extirpado el apéndice?";
        case 44:
            return "¿Tienes ictericia? "
                ~ "(La ictericia no es una enfermedad, sino un síntoma. "
                ~ "Con frecuencia es más patente en los ojos: "
                ~ "la parte blanca se torna amarillenta).";
        case 45:
            return "¿Te sientes tenso o inquieto?";
        case 46:
            return "¿Te cuesta conciliar el sueño, "
                ~ "o te desvelas frecuentemente por la noche?";
        case 47:
            return "¿Tienes contracciones involuntarias o temblores?";
        case 48:
            return "¿Sufres de estreñimiento, o sueles tener crisis de estreñimiento?";
        case 49:
            return "¿Te falla la memoria, "
                ~ "tienes dificultad para recordar hechos aislados, "
                ~ "ya sea ocasional o regularmente?";
        case 50:
            return "¿Sufres afasia, es decir, "
                ~ "has perdido capacidad para expresarte con palabras?";
        case 51:
            return "¿Has tenido alguna hemorragia por el recto?";
        case 52:
            return "¿Eres hombre o mujer? Responde con 5 para hombre y -5 para mujer. "
                ~ "Una respuesta 0 hace que el diagnóstico sea independiente del sexo.";
        case 53:
            return "¿Tienes rigidez o dolor en el cuello?";
        case 54:
            return "¿Has sufrido algún golpe o herida de cualquier tipo en la cabeza "
                ~ "durante las últimas semanas? "
                ~ "(Un golpe incluso leve puede ser importante).";
        case 55:
            return "¿Has expulsado recientemente heces de aspecto anormal?";
        case 56:
            return "¿Expulsas muchos gases, por cualquier vía?";
        case 57:
            return "¿Tienes sensaciones repentinas de desmayo, es decir, "
                ~ "de sentirte desfallecido y mareado, incluso, "
                ~ "quizás con pérdida de consciencia?";
        case 58:
            return "¿Te pica alguna parte del cuerpo, tengas o no erupción en ella?";
        case 59:
            return "¿Tienes alguna erupción o lesión de cualquier tipo en la piel?";
        case 60:
            return "¿Tienes alguna parte del cuerpo entumecida, "
                ~ "o con sensación de comezón u hormigueo, como de «agujas y alfileres»?";
        case 61:
            return "¿Es tu peso anormal? "
                ~ "Responde con 5 para un peso excesivamente elevado, "
                ~ "con -5 si es excesivamente bajo y con 0 si es normal.";
        case 62:
            return "¿Sufres de algún dolor en la cara o en la frente?";
        case 63:
            return "¿Tienes algún bulto, hinchazón o abultamiento, "
                ~ "en cualquier parte del cuerpo?";
        case 64:
            return "¿Es anormal el color de tu orina?";
        case 65:
            return "¿Orinas con una frecuencia anormal?";
        case 66:
            return "¿Tienes dolores al orinar?";
        case 67:
            return "¿Tienes alguna anormalidad en la visión, "
                ~ "como ver borroso o doble, o luces destelleantes? "
                ~ "(No cuentan los defectos que pueden corregirse con gafas).";
        default:
            return "";
    }
}

// user_input.d
//
// This file is part of Experto en enfermedades (Expert on diseases)

// Last modified 20250812T1903+0200.

/*

Copyright (C) 1985, Chris Naylor: Sinclair BASIC code included in his book
"Build Your Own Expert System" (Sigma Press, 1985).

Copyright (C) 1988, 1989, Marcos Cruz (programandala.net): SuperBASIC version
(http:///programandala.net/es.programa.sistema_experto_sobre_enfermedades.html).

Copyright (C) 2023, 2024, Marcos Cruz (programandala.net): Odin version.

Copyright (C) 2024, 2025, Marcos Cruz (programandala.net): SBASIC version.

Copyright (C) 2025, Marcos Cruz (programandala.net): V version.

Copyright (C) 2025, Marcos Cruz (programandala.net): D version.

This program is licensed under a BSD 2-Clause License
(https://opensource.org/license/bsd-2-clause/). See the <LICENSE.txt> file.

*/

// ==========================================================================

module user_input;

import std.algorithm.searching :
    starts_with = startsWith;
import std.conv :
    to;
import std.stdio :
    readln,
    write,
    writeln;
import std.format :
    format;
import std.random :
    choice;
import std.range :
    iota;
import std.string :
    index_of = indexOf,
    strip;
import std.uni :
    to_lower = toLower;

import par = ditto.par;

import main;

/// Maximun value of a user's answer.

enum int MAX_ANSWER = 5;

/// Minimum value of a user's answer.

enum MIN_ANSWER = -MAX_ANSWER;

/// A user answer: its value and an ok flag indicating the value is valid.

struct Answer{
    int value;
    bool ok;
}

/// Default prompt.

enum string DEFAULT_PROMPT = "> ";

/// Print the given or [default prompt][DEFAULT_PROMPT], read and return user's
/// input.

string user_input_string(string prompt = DEFAULT_PROMPT)
{
    write(prompt);
    return strip(readln());
}

/// Print the menu of user's commands.

void print_menu()
{
    debug
    {
        par.whole("Comandos:");
    }
    else
    {
        par.whole("Comandos principales:");
    }
    par.whole("- Consultar");
    par.whole("- Finalizar");
    debug
    {
        par.whole("Comandos para depuración:");
        par.whole("- Probar (modo automático con respuestas aleatorias)");
        par.whole(
            format(
                "- Número de %s a %s (modo automático con respuesta única)",
                MIN_ANSWER,
                MAX_ANSWER
            )
        );
    }
}

/// Print the command menu and accept a command from the user. If it's a valid
/// command set the corresponding configuration and return `true`.  Othewiser
/// return `false`.

bool ready()
{
    while (true)
    {
        print_menu();
        string answer = to_lower(user_input_string());
        if (starts_with("consultar", answer))
        {
            mode = Mode.Normal;
            return true;
        }
        else if (starts_with("finalizar", answer))
        {
            return false;
        }
        else if (starts_with("probar", answer))
        {
            debug
            {
                mode = Mode.Random_Demo;
                return true;
            }
        }
        else
        {
            debug
            {
                Answer the_answer = valid_answer(answer);
                if (the_answer.ok)
                {
                    mode = Mode.Value_Demo;
                    demo_value = the_answer.value;
                    return true;
                }
            }
        }
    }
    return false;
}

/// Ask the user to press the enter key and wait for it.

void press_enter()
{
    par.cr();
    par.whole("Pulsa la tecla «intro» para empezar.");
    user_input_string();
}

/// Check the given user answer string and return its info in an [Answer]
/// structure.

Answer valid_answer(string answer)
{
    switch (answer.length)
    {
        case 1:
            if (index_of("012345", answer) == -1)
            {
                return Answer(0, false);
            }
            break;
        case 2:
            if (index_of("+-", answer[0 .. 1]) == -1)
            {
                return Answer(0, false);
            }
            if (index_of("012345", answer[1 .. 2]) == -1)
            {
                return Answer(0, false);
            }
            break;
        default:
            return Answer(0, false);
    }
    int value;
    try
    {
        value = to!int(answer);
        return Answer(value, true);
    }
    catch (Exception)
    {
        return Answer(0, false);
    }
}

/// Prompt the user for a valid answer, check it and return it.

int user_answer()
{
    Answer answer;
    while (true)
    {
        par.whole
        (
            format
            (
                "Responde con un número de %s a %s:",
                MIN_ANSWER,
                MAX_ANSWER
            )
        );
        par.whole
        (
            format
            (
                "%s (no, nunca) … 0 … %s (sí, siempre)",
                MIN_ANSWER,
                MAX_ANSWER
            )
        );
        answer = valid_answer(user_input_string());
        if (answer.ok)
        {
            break;
        }
    }
    return answer.value;
}

/// Return a random number from [MIN_ANSWER] to [MAX_ANSWER], inclusive.

int random_answer()
{
    return choice(iota(MIN_ANSWER, MAX_ANSWER + 1));
}

// version_number.d
//
// This file is part of Experto en enfermedades (Expert on diseases)

// Last modified 20250812T1903+0200.

/*

Copyright (C) 1985, Chris Naylor: Sinclair BASIC code included in his book
"Build Your Own Expert System" (Sigma Press, 1985).

Copyright (C) 1988, 1989, Marcos Cruz (programandala.net): SuperBASIC version
(http:///programandala.net/es.programa.sistema_experto_sobre_enfermedades.html).

Copyright (C) 2024, 2025, Marcos Cruz (programandala.net): SBASIC version.

Copyright (C) 2023, 2024, Marcos Cruz (programandala.net): Odin version.

Copyright (C) 2025, Marcos Cruz (programandala.net): V version.

Copyright (C) 2025, Marcos Cruz (programandala.net): D version.

This program is licensed under a BSD 2-Clause License
(https://opensource.org/license/bsd-2-clause/). See the <LICENSE.txt> file.

*/

// ==========================================================================

module version_number;

/// Version number.

enum string VERSION = "0.1.0-dev.0.28.2+20250812T1903CEST";

Descargas

La descarga estará disponible tras la publicación del repositorio.

Páginas relacionadas

Experto en enfermedades (versión en SuperBASIC)
Sistema experto sobre enfermedades, escrito en SuperBASIC para el sistema operativo QDOS y compatibles.
Experto en enfermedades (versión en Odin)
Sistema experto sobre enfermedades, escrito en Odin.
Experto en enfermedades (versión en SBASIC)
Sistema experto sobre enfermedades, escrito en SBASIC para el sistema operativo SMSQ/E.
Experto en enfermedades (versión en V)
Sistema experto sobre enfermedades, escrito en V.