Experto en enfermedades (versión en Odin)

Descripción del contenido de la página

Sistema experto sobre enfermedades, escrito en Odin.

Etiquetas:

Código fuente

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

// Last modified 20250626T0103+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.

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

*/

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

package eee

import "../lib/anodino/src/par"
import "../lib/anodino/src/term"
import "../lib/anodino/src/type"
import "core:fmt"
import "core:math"

TITLE :: "Experto en enfermedades"

// Set the debug level, taken from the `--define:DEBUG_LEVEL=X` compilation option
// where `X` can be a number between 0 and 2:
// 0: do not include debug code (this is the default)
// 1: add the test options to the main menu
// 2: also print debugging messages during the main loop
DEBUG_LEVEL :: #config(DEBUG_LEVEL, 0)

MAX_ANSWER :: 5
MIN_ANSWER :: -MAX_ANSWER

Mode       :: enum { Normal, Random_Demo, Value_Demo }
mode       : Mode
demo_value : int  // used in value demo mode

init :: proc() {

    // Anodino's type package is used by Anodino's par package. When type's
    // `max_lines_printed_before_a_pause` is set to zero, no pause is issued
    // during the printing of the paragrahps:
    type.max_lines_printed_before_a_pause = 0

}

consult :: proc() {

    DISEASES :: 91
    SYMPTOMS :: 68

    max_prob       := [DISEASES]f64{}
    min_prob       := [DISEASES]f64{}
    prob           := [DISEASES]f64{}
    asked          := [SYMPTOMS]bool{}
    symptoms_count := [DISEASES]int{}
    symptoms_left  := [DISEASES]int{}
    value          := [SYMPTOMS]f64{}

    answer_value : int
    disease_name : string
    disease_prob : f64
    hypothesis   : int
    symptom      : int

    current_prob : f64
    con_prob     : f64
    pro_prob     : f64

    // Find the a priori probability and the rule values
    when DEBUG_LEVEL > 1 {
        fmt.println("Find the a priori probability and the rule values")
    }

    for disease in 0 ..< DISEASES {
        disease_name, prob[disease] = disease_data(disease)
        current_prob = prob[disease]
        when DEBUG_LEVEL > 1 {
            fmt.printf("Disease #%v: \"%v\" (current prob: %v)\n", disease, disease_name, current_prob)
        }
        for disease_symptom := 0 ; ; disease_symptom += 1 {
            symptom, pro_prob, con_prob = symptom_data(disease, disease_symptom) or_break
            symptoms_left[disease] += 1
            value[symptom] +=
                math.abs( \
                        current_prob * pro_prob \
                        / (current_prob * pro_prob + (1 - current_prob) * con_prob) \
                    - \
                        current_prob * (1 - pro_prob) \
                        / (current_prob * (1 - pro_prob) + (1 - current_prob) * (1 - con_prob)) \
                )
            when DEBUG_LEVEL > 1 {
                fmt.printf("Symptom #%v (value: %v)\n", symptom, value[symptom])
            }
        }
        symptoms_count[disease] = symptoms_left[disease]
    }

    for {

        // Find the most important symptom and ask about it
        when DEBUG_LEVEL > 1 {
            fmt.println("Find the most important symptom and ask about it")
        }

        min_value : f64 = 0
        NO_SYMPTOM :: -1
        symptom_to_ask_for := NO_SYMPTOM
        for symptom in 0 ..< SYMPTOMS {
            if value[symptom] > min_value {
                symptom_to_ask_for = symptom
                min_value = value[symptom]
                when DEBUG_LEVEL > 1 {
                    fmt.printf("Symptom to ask for: #%v, \"%v\" (value: %v)\n", 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
        }
        when DEBUG_LEVEL == 0 {
            if mode == .Normal do term.clear_screen()
        }
        par.whole(question(symptom_to_ask_for))
        switch mode {
            case .Random_Demo :
                answer_value = random_answer()
                par.whole(fmt.tprintf("%v", answer_value))
            case .Value_Demo :
                answer_value = demo_value
                par.whole(fmt.tprintf("%v", answer_value))
            case .Normal :
                answer_value = user_answer()
        }
        asked[symptom_to_ask_for] = true

        // Update the a priori probabilities
        when DEBUG_LEVEL > 1 {
            fmt.println("Update the a priori probabilities")
        }

        for disease in 0 ..< DISEASES {
            disease_name, _ = disease_data(disease)
            when DEBUG_LEVEL > 1 {
                fmt.printf("Disease #%v: \"%v\"\n", disease, disease_name)
            }
            for s in 0 ..< symptoms_count[disease] {
                symptom, pro_prob, con_prob, _ = symptom_data(disease, s)
                if symptom == symptom_to_ask_for && symptoms_left[disease] > 0 {
                    symptoms_left[disease] = symptoms_left[disease] - 1
                    current_prob = prob[disease]
                    pe := current_prob * pro_prob + (1 - current_prob) * con_prob
                    if answer_value > 0 {
                        prob[disease] = \
                            current_prob \
                            * (1 + (pro_prob / pe - 1) * f64(answer_value) \
                                / MAX_ANSWER)
                    } else {
                        prob[disease] = \
                            current_prob \
                            * (1 \
                                + (pro_prob - (1 - pro_prob) * pe / (1 - pe)) \
                                * f64(answer_value) / MAX_ANSWER)
                    }
                    if prob[disease] == math.trunc(prob[disease]) {
                        symptoms_left[disease] = 0
                    }
                }
            }
        }

        // Find new min and max rule values

        current_min_prob : f64
        for disease in 0 ..< DISEASES {
            current_prob = prob[disease]
            a1 : f64 = 1
            a2 : f64 = 1
            a3 : f64 = 1
            a4 : f64 = 1
            disease_name, disease_prob = disease_data(disease)
            for s in 0 ..< symptoms_count[disease] {
                symptom, pro_prob, con_prob, _ = symptom_data(disease, s)
                if ! asked[symptom] && symptoms_left[disease] > 0 {
                    if con_prob > pro_prob {
                        pro_prob = 1 - pro_prob
                        con_prob = 1 - con_prob
                    }
                    value[symptom] = \
                        value[symptom] \
                        + current_prob * pro_prob \
                            / (current_prob * pro_prob + (1 - current_prob) * con_prob) \
                        - current_prob * (1 - pro_prob) \
                            / (current_prob * (1 - pro_prob) + (1 - current_prob) * (1 - con_prob))
                    a1 = a1 * pro_prob
                    a2 = a2 * con_prob
                    a3 = a3 * (1 - pro_prob)
                    a4 = a4 * (1 - con_prob)
                }
            }
            max_prob[disease] = current_prob * a1 / (current_prob * a1 + (1 - current_prob) * a2)
            min_prob[disease] = current_prob * a3 / (current_prob * a3 + (1 - current_prob) * a4)
            if max_prob[disease] < disease_prob {
                symptoms_left[disease] = 0
            }
            if min_prob[disease] > current_min_prob {
                hypothesis = disease
                current_min_prob = min_prob[disease]
                when DEBUG_LEVEL > 1 {
                    disease_name, _ := disease_data(hypothesis)
                    fmt.printf("Hipótesis: %v (#%v), probabilidad mínima: %v\n", disease_name, hypothesis, current_min_prob)
                }
            }
        }

        // Search for a clearly possible hypothesis

        for disease in 0 ..< DISEASES {
            if min_prob[hypothesis] <= max_prob[disease] && disease != hypothesis {
                current_min_prob = 0
            }
        }
        if current_min_prob != 0 do break

    }

    disease_name, _ = disease_data(hypothesis)
    par.whole(
        fmt.tprintf(
            "El resultado más probable es %v con probabilidad %v.",
            disease_name,
            prob[hypothesis]
        )
    )

}

print_credits :: proc() {
    par.whole(TITLE)
    par.whole(fmt.tprintf("Versión %v", VERSION))
    fmt.println()
    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.")
    fmt.println()
}

main :: proc() {
    init()
    for {
        term.clear_screen()
        print_credits()
        if ready() {
            consult()
            press_enter()
        } else {
            break
        }
    }
}

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

// Last modified 20250624T2035+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.

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

*/

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

package eee

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

// Return probabilities of the given disease and symptom, and a flag to
// indicate whether the list of symptoms of the given disease is exhausted.
symptom_data :: proc(disease, disease_symptom : int ) ->
    (symptom: int, pro_prob, con_prob: f64, ok: bool) {
    switch disease {
        case 0:
            switch disease_symptom {
                case 0: return 0, .9, 0.05, true
                case 1: return 1, .8, 0.02, true
                case 2: return 2, .8, 0.02, true
                case 3: return 4, .6, 0.01, true
                case 4: return 5, 1, 0.01, true
                case 5: return 6, .2, 0.01, true
                case 6: return 7, .5, 0.01, true
                case 7: return 14, .8, 0.01, true
                case 8: return 33, 0, 0.01, true
            }
        case 1:
            switch disease_symptom {
                case 0: return 0, 1, 0.01, true
                case 1: return 1, 1, 0.01, true
                case 2: return 5, .9, 0.01, true
                case 3: return 9, .7, 0.01, true
                case 4: return 10, .7, 0.01, true
                case 5: return 11, .6, 0.01, true
                case 6: return 19, .9, 0.01, true
            }
        case 2:
            switch disease_symptom {
                case 0: return 1, .5, 0.01, true
                case 1: return 5, .5, 0.01, true
                case 2: return 6, .8, 0.01, true
                case 3: return 12, .9, 0.01, true
                case 4: return 13, .8, 0.01, true
                case 5: return 14, .8, 0.01, true
                case 6: return 21, .5, 0.01, true
                case 7: return 62, .9, 0.01, true
            }
        case 3:
            switch disease_symptom {
                case 0: return 2, 1, 0.01, true
                case 1: return 7, .5, 0.01, true
                case 2: return 10, .9, 0.01, true
                case 3: return 15, .9, 0.01, true
                case 4: return 36, .8, .3, true
                case 5: return 63, .4, 0.01, true
            }
        case 4:
            switch disease_symptom {
                case 0: return 2, 1, 0.01, true
                case 1: return 6, .9, 0.01, true
                case 2: return 7, .9, 0.01, true
                case 3: return 14, 1, 0.01, true
                case 4: return 15, .7, 0.01, true
                case 5: return 18, 0, .5, true
                case 6: return 33, 0, 0.01, true
                case 7: return 63, .8, 0.01, true
            }
        case 5:
            switch disease_symptom {
                case 0: return 0, .9, 0.01, true
                case 1: return 2, .9, 0.01, true
                case 2: return 5, .5, 0.01, true
                case 3: return 6, .7, 0.01, true
                case 4: return 7, 1, 0.01, true
                case 5: return 14, 1, 0.01, true
                case 6: return 16, .8, 0.01, true
                case 7: return 17, .6, 0.01, true
                case 8: return 33, 0, 0.01, true
            }
        case 6:
            switch disease_symptom {
                case 0: return 3, 1, 0.01, true
                case 1: return 4, .9, 0.01, true
                case 2: return 7, .6, 0.01, true
                case 3: return 14, 0.05, 0.01, true
                case 4: return 15, .7, 0.01, true
                case 5: return 36, .8, .3, true
                case 6: return 20, .1, 0.01, true
            }
        case 7:
            switch disease_symptom {
                case 0: return 3, 1, 0.01, true
                case 1: return 33, .99, 0.01, true
                case 2: return 36, .8, .3, true
            }
        case 8:
            switch disease_symptom {
                case 0: return 4, 1, 0.01, true
                case 1: return 7, 1, 0.01, true
                case 2: return 11, 1, 0.01, true
                case 3: return 14, 1, 0.01, true
                case 4: return 17, .5, 0.01, true
                case 5: return 20, 1, 0.01, true
                case 6: return 21, .9, 0.01, true
                case 7: return 30, .9, 0.01, true
                case 8: return 33, 0, 0.01, true
            }
        case 9:
            switch disease_symptom {
                case 0: return 4, 1, 0.01, true
                case 1: return 11, .9, 0.01, true
                case 2: return 13, .5, 0.01, true
                case 3: return 20, 1, 0.01, true
                case 4: return 21, .8, 0.01, true
                case 5: return 33, 1, 0.01, true
                case 6: return 35, .9, 0.01, true
                case 7: return 36, .8, .3, true
            }
        case 10:
            switch disease_symptom {
                case 0: return 11, .8, 0.01, true
                case 1: return 21, 1, 0.01, true
                case 2: return 22, .5, 0.01, true
                case 3: return 23, .5, 0.01, true
                case 4: return 24, .5, 0.01, true
                case 5: return 25, .5, 0.01, true
                case 6: return 30, .8, 0.01, true
            }
        case 11:
            switch disease_symptom {
                case 0: return 4, .6, 0.01, true
                case 1: return 11, .6, 0.01, true
                case 2: return 20, .6, 0.01, true
                case 3: return 21, 1, 0.01, true
                case 4: return 25, .8, 0.01, true
                case 5: return 36, .8, .3, true
            }
        case 12:
            switch disease_symptom {
                case 0: return 7, 1, 0.01, true
                case 1: return 14, 1, 0.01, true
                case 2: return 16, .9, 0.01, true
                case 3: return 17, .8, 0.01, true
                case 4: return 21, 1, 0.01, true
                case 5: return 22, .5, 0.01, true
                case 6: return 25, .5, 0.01, true
                case 7: return 26, .2, 0.01, true
                case 8: return 27, .1, 0.01, true
                case 9: return 28, 0.02, 0.01, true
                case 10: return 30, .9, 0.01, true
                case 11: return 31, .5, 0.005, true
                case 12: return 35, .1, .9, true
            }
        case 13:
            switch disease_symptom {
                case 0: return 4, .8, 0.01, true
                case 1: return 7, .9, 0.01, true
                case 2: return 14, 1, 0.01, true
                case 3: return 21, .5, 0.01, true
                case 4: return 30, .8, 0.01, true
                case 5: return 31, .8, 0.01, true
                case 6: return 33, 0, 0.01, true
            }
        case 14:
            switch disease_symptom {
                case 0: return 17, .8, 0.01, true
                case 1: return 21, .8, 0.01, true
                case 2: return 31, .8, 0.005, true
            }
        case 15:
            switch disease_symptom {
                case 0: return 4, 1, 0.01, true
                case 1: return 13, .5, 0.01, true
                case 2: return 20, 1, 0.01, true
                case 3: return 26, .5, 0.01, true
            }
        case 16:
            switch disease_symptom {
                case 0: return 17, .5, 0.01, true
                case 1: return 20, .5, 0.01, true
                case 2: return 26, .5, 0.01, true
                case 3: return 32, .9, 0.01, true
            }
        case 17:
            switch disease_symptom {
                case 0: return 8, 1, 0.01, true
                case 1: return 20, .8, 0.01, true
                case 2: return 21, 1, 0.01, true
                case 3: return 35, 1, 0.01, true
            }
        case 18:
            switch disease_symptom {
                case 0: return 4, 1, 0.01, true
                case 1: return 11, .5, 0.01, true
                case 2: return 17, .8, 0.01, true
                case 3: return 20, .8, 0.01, true
                case 4: return 21, .5, 0.01, true
                case 5: return 26, .5, 0.01, true
                case 6: return 36, .99, .3, true
            }
        case 19:
            switch disease_symptom {
                case 0: return 20, .6, 0.01, true
                case 1: return 21, .8, 0.01, true
                case 2: return 34, .8, 0.01, true
            }
        case 20:
            switch disease_symptom {
                case 0: return 11, .8, 0.01, true
                case 1: return 21, .9, 0.01, true
                case 2: return 24, .9, 0.01, true
                case 3: return 25, .5, 0.01, true
                case 4: return 26, .5, 0.01, true
                case 5: return 29, .5, 0.01, true
            }
        case 21:
            switch disease_symptom {
                case 0: return 7, .4, 0.01, true
                case 1: return 36, .9, .5, true
                case 2: return 40, 0.01, .8, true
                case 3: return 42, .8, 0.01, true
                case 4: return 41, .5, 0.01, true
            }
        case 22:
            switch disease_symptom {
                case 0: return 15, .9, 0.01, true
                case 1: return 17, .9, 0.01, true
                case 2: return 31, .5, 0.005, true
                case 3: return 40, .8, 0.01, true
                case 4: return 41, .8, 0.005, true
                case 5: return 56, .9, 0.01, true
            }
        case 23:
            switch disease_symptom {
                case 0: return 36, .8, .2, true
                case 1: return 40, .8, 0.01, true
                case 2: return 41, .99, 0.005, true
                case 3: return 56, .7, 0.01, true
            }
        case 24:
            switch disease_symptom {
                case 0: return 19, .8, 0.01, true
                case 1: return 40, .7, 0.01, true
                case 2: return 41, .9, 0.005, true
                case 3: return 45, .5, 0.01, true
                case 4: return 55, .9, 0.01, true
                case 5: return 61, 0.0001, 0.01, true
            }
        case 25:
            switch disease_symptom {
                case 0: return 7, .5, 0.01, true
                case 1: return 40, .5, 0.01, true
                case 2: return 41, .6, 0.005, true
                case 3: return 42, .5, 0.01, true
                case 4: return 55, .8, 0.01, true
            }
        case 26:
            switch disease_symptom {
                case 0: return 7, .3, 0.01, true
                case 1: return 22, .3, 0.01, true
                case 2: return 40, .3, 0.01, true
                case 3: return 41, .9, 0.005, true
                case 4: return 42, .7, 0.01, true
            }
        case 27:
            switch disease_symptom {
                case 0: return 7, .7, 0.01, true
                case 1: return 14, .9, 0.01, true
                case 2: return 41, .9, 0.005, true
                case 3: return 42, .9, 0.01, true
                case 4: return 61, 0.00001, 0.01, true
            }
        case 28:
            switch disease_symptom {
                case 0: return 40, .5, 0.01, true
                case 1: return 41, .9, 0.005, true
                case 2: return 42, .8, 0.01, true
            }
        case 29:
            switch disease_symptom {
                case 0: return 7, .8, 0.01, true
                case 1: return 33, .1, .9, true
                case 2: return 40, .8, 0.01, true
                case 3: return 41, .9, 0.005, true
                case 4: return 43, 0, .5, true
            }
        case 30:
            switch disease_symptom {
                case 0: return 6, .8, 0.01, true
                case 1: return 40, .9, 0.01, true
                case 2: return 41, .5, 0.005, true
                case 3: return 42, .9, 0.01, true
            }
        case 31:
            switch disease_symptom {
                case 0: return 7, .5, 0.01, true
                case 1: return 40, .8, 0.01, true
                case 2: return 41, .7, 0.005, true
                case 3: return 42, .9, 0.01, true
            }
        case 32:
            switch disease_symptom {
                case 0: return 41, .7, 0.005, true
            }
        case 33:
            switch disease_symptom {
                case 0: return 7, .8, 0.01, true
                case 1: return 40, .7, 0.01, true
                case 2: return 41, .9, 0.005, true
                case 3: return 66, .9, 0.01, true
            }
        case 34:
            switch disease_symptom {
                case 0: return 40, .5, 0.01, true
                case 1: return 41, .5, 0.005, true
                case 2: return 56, .9, 0.01, true
            }
        case 35:
            switch disease_symptom {
                case 0: return 7, .9, 0.01, true
                case 1: return 40, .8, 0.01, true
                case 2: return 41, .8, 0.005, true
                case 3: return 44, .8, 0.001, true
            }
        case 36:
            switch disease_symptom {
                case 0: return 1, .6, 0.01, true
                case 1: return 7, .5, 0.01, true
                case 2: return 13, .8, 0.01, true
                case 3: return 17, .5, 0.01, true
                case 4: return 58, .9, 0.01, true
                case 5: return 59, .9, 0.01, true
            }
        case 37:
            switch disease_symptom {
                case 0: return 39, .8, 0.01, true
            }
        case 38:
            switch disease_symptom {
                case 0: return 14, .8, 0.01, true
                case 1: return 16, .8, 0.01, true
                case 2: return 39, .5, 0.001, true
            }
        case 39:
            switch disease_symptom {
                case 0: return 11, .6, 0.01, true
                case 1: return 17, .5, 0.01, true
                case 2: return 21, .9, 0.01, true
                case 3: return 24, .5, 0.001, true
                case 4: return 25, .3, 0.001, true
                case 5: return 31, .3, 0.001, true
                case 6: return 35, .5, 0.01, true
                case 7: return 38, .5, 0.01, true
                case 8: return 41, .5, 0.01, true
                case 9: return 46, .9, 0.01, true
            }
        case 40:
            switch disease_symptom {
                case 0: return 6, .5, 0.01, true
                case 1: return 14, .5, 0.01, true
                case 2: return 15, .3, 0.01, true
                case 3: return 21, .5, 0.01, true
                case 4: return 22, .6, 0.01, true
                case 5: return 27, .3, 0.01, true
                case 6: return 37, .5, 0.01, true
                case 7: return 38, .8, 0.01, true
                case 8: return 42, .2, 0.01, true
                case 9: return 45, .9, 0.01, true
                case 10: return 46, .6, 0.01, true
                case 11: return 47, .6, 0.01, true
                case 12: return 49, .5, 0.01, true
                case 13: return 56, .5, 0.01, true
                case 14: return 57, .5, 0.01, true
            }
        case 41:
            switch disease_symptom {
                case 0: return 6, .5, 0.01, true
                case 1: return 14, .5, 0.01, true
                case 2: return 46, .5, 0.01, true
                case 3: return 48, .5, 0.01, true
                case 4: return 49, .5, 0.01, true
                case 5: return 61, .8, 0.01, true
            }
        case 42:
            switch disease_symptom {
                case 0: return 14, .9, 0.01, true
                case 1: return 17, .5, 0.01, true
                case 2: return 19, .5, 0.01, true
                case 3: return 21, .5, 0.01, true
                case 4: return 22, .5, 0.01, true
                case 5: return 31, .9, 0.001, true
                case 6: return 35, 0, .2, true
                case 7: return 37, .5, 0.01, true
                case 8: return 40, .5, 0.01, true
            }
        case 43:
            switch disease_symptom {
                case 0: return 17, .9, 0.01, true
                case 1: return 19, .9, 0.01, true
                case 2: return 21, .5, 0.01, true
                case 3: return 22, .5, 0.01, true
                case 4: return 31, 1, 0.001, true
                case 5: return 35, .9, 0.01, true
                case 6: return 36, .8, .3, true
                case 7: return 37, .5, 0.01, true
            }
        case 44:
            switch disease_symptom {
                case 0: return 17, .7, 0.01, true
                case 1: return 20, .6, 0.01, true
                case 2: return 21, 1, 0.01, true
                case 3: return 24, .5, 0.001, true
                case 4: return 25, .4, 0.001, true
                case 5: return 26, .5, 0.001, true
            }
        case 45:
            switch disease_symptom {
                case 0: return 27, .8, 0.01, true
                case 1: return 37, .7, 0.01, true
                case 2: return 50, .8, 0.001, true
                case 3: return 57, .9, 0.01, true
                case 4: return 60, .9, 0.01, true
            }
        case 46:
            switch disease_symptom {
                case 0: return 19, .5, 0.01, true
                case 1: return 27, .8, 0.01, true
                case 2: return 33, 0, 0.01, true
                case 3: return 37, .7, 0.01, true
                case 4: return 50, .8, 0.001, true
                case 5: return 57, .9, 0.01, true
                case 6: return 60, .9, 0.01, true
            }
        case 47:
            switch disease_symptom {
                case 0: return 4, .5, 0.01, true
                case 1: return 6, .5, 0.01, true
                case 2: return 7, .5, 0.01, true
                case 3: return 11, .5, 0.01, true
                case 4: return 14, .5, 0.01, true
                case 5: return 17, .5, 0.01, true
                case 6: return 21, .5, 0.01, true
                case 7: return 22, .5, 0.01, true
                case 8: return 26, .5, 0.001, true
                case 9: return 29, .5, 0.01, true
                case 10: return 61, 0.0001, 0.01, true
            }
        case 48:
            switch disease_symptom {
                case 0: return 48, .8, 0.01, true
                case 1: return 51, .9, 0.001, true
                case 2: return 55, .9, 0.01, true
                case 3: return 58, .5, 0.01, true
            }
        case 49:
            switch disease_symptom {
                case 0: return 3, .5, 0.01, true
                case 1: return 16, .5, 0.01, true
                case 2: return 22, 0.001, 0.01, true
                case 3: return 23, 0, 0.01, true
                case 4: return 38, 0.001, 0.01, true
                case 5: return 42, 0, 0.01, true
                case 6: return 45, 0.001, 0.01, true
                case 7: return 47, 0.001, 0.01, true
                case 8: return 48, .8, 0.01, true
                case 9: return 61, .9, 0.05, true
            }
        case 50:
            switch disease_symptom {
                case 0: return 40, .3, 0.01, true
                case 1: return 41, .8, 0.001, true
                case 2: return 42, .5, 0.01, true
                case 3: return 48, .5, 0.01, true
                case 4: return 55, .5, 0.01, true
                case 5: return 56, .9, 0.01, true
            }
        case 51:
            switch disease_symptom {
                case 0: return 41, .5, 0.005, true
                case 1: return 42, .9, 0.01, true
                case 2: return 48, .9, 0.01, true
                case 3: return 51, .5, 0.001, true
                case 4: return 55, .9, 0.01, true
                case 5: return 61, 0.0001, 0.01, true
            }
        case 52:
            switch disease_symptom {
                case 0: return 7, .5, 0.01, true
                case 1: return 22, .5, 0.01, true
                case 2: return 33, .4, 0.01, true
                case 3: return 40, .5, 0.01, true
                case 4: return 41, .8, 0.005, true
                case 5: return 42, .8, 0.01, true
                case 6: return 51, .6, 0.001, true
                case 7: return 55, .9, 0.01, true
            }
        case 53:
            switch disease_symptom {
                case 0: return 19, .9, 0.01, true
                case 1: return 33, .5, 0.01, true
                case 2: return 37, .9, 0.001, true
                case 3: return 40, .8, 0.01, true
            }
        case 54:
            switch disease_symptom {
                case 0: return 6, .5, 0.01, true
                case 1: return 37, .5, 0.01, true
                case 2: return 53, .9, 0.01, true
                case 3: return 57, .9, 0.01, true
                case 4: return 60, .5, 0.01, true
            }
        case 55:
            switch disease_symptom {
                case 0: return 6, .9, 0.01, true
                case 1: return 19, .5, 0.01, true
                case 2: return 27, .9, 0.001, true
                case 3: return 33, .5, 0.01, true
                case 4: return 37, .9, 0.01, true
                case 5: return 40, .9, 0.01, true
                case 6: return 54, .99, 0.001, true
            }
        case 56:
            switch disease_symptom {
                case 0: return 6, .9, 0.01, true
                case 1: return 33, .5, 0.01, true
                case 2: return 37, .8, 0.01, true
                case 3: return 40, .9, 0.01, true
                case 4: return 49, .8, 0.01, true
            }
        case 57:
            switch disease_symptom {
                case 0: return 1, .9, 0.01, true
                case 1: return 6, .9, 0.01, true
                case 2: return 7, .9, 0.01, true
                case 3: return 27, .7, 0.01, true
                case 4: return 40, .9, 0.01, true
                case 5: return 53, .9, 0.01, true
                case 6: return 59, .5, 0.01, true
            }
        case 58:
            switch disease_symptom {
                case 0: return 1, .8, 0.01, true
                case 1: return 6, .99, 0.01, true
                case 2: return 27, .7, 0.01, true
                case 3: return 37, .7, 0.01, true
                case 4: return 40, .8, 0.01, true
                case 5: return 53, .9, 0.01, true
            }
        case 59:
            switch disease_symptom {
                case 0: return 1, .9, 0.01, true
                case 1: return 6, .9, 0.01, true
                case 2: return 19, .8, 0.01, true
                case 3: return 33, .8, 0.01, true
                case 4: return 40, .7, 0.01, true
                case 5: return 62, .9, 0.01, true
                case 6: return 67, .9, 0.01, true
            }
        case 60:
            switch disease_symptom {
                case 0: return 6, .9, 0.01, true
                case 1: return 7, .7, 0.01, true
                case 2: return 16, .7, 0.01, true
                case 3: return 22, .8, 0.01, true
                case 4: return 62, .99, 0.01, true
            }
        case 61:
            switch disease_symptom {
                case 0: return 6, .7, 0.01, true
                case 1: return 19, .9, 0.01, true
                case 2: return 40, .7, 0.01, true
                case 3: return 41, .7, 0.01, true
                case 4: return 56, .7, 0.01, true
                case 5: return 61, 0.001, 0.01, true
            }
        case 62:
            switch disease_symptom {
                case 0: return 17, .6, 0.01, true
                case 1: return 21, .5, 0.01, true
                case 2: return 38, .6, 0.01, true
                case 3: return 57, .8, 0.01, true
            }
        case 63:
            switch disease_symptom {
                case 0: return 21, .9, 0.01, true
                case 1: return 27, .4, 0.01, true
                case 2: return 35, .9, 0.01, true
                case 3: return 38, .9, 0.01, true
                case 4: return 41, .5, 0.01, true
                case 5: return 44, .5, 0.01, true
                case 6: return 49, .5, 0.01, true
                case 7: return 57, .9, 0.01, true
            }
        case 64:
            switch disease_symptom {
                case 0: return 1, .9, 0.01, true
                case 1: return 6, 1, 0.01, true
                case 2: return 14, .9, 0.01, true
                case 3: return 19, .9, 0.01, true
                case 4: return 33, .9, 0.01, true
                case 5: return 40, .9, 0.01, true
                case 6: return 42, .5, 0.01, true
                case 7: return 62, .99, 0.01, true
            }
        case 65:
            switch disease_symptom {
                case 0: return 6, .5, 0.01, true
                case 1: return 14, .9, 0.01, true
                case 2: return 33, .9, 0.01, true
                case 3: return 38, .5, 0.01, true
            }
        case 66:
            switch disease_symptom {
                case 0: return 58, .9, 0.01, true
                case 1: return 59, .1, 0.01, true
            }
        case 67:
            switch disease_symptom {
                case 0: return 45, .5, 0.01, true
                case 1: return 58, .9, 0.01, true
                case 2: return 59, 1, 0.01, true
            }
        case 68:
            switch disease_symptom {
                case 0: return 58, 1, 0.01, true
                case 1: return 59, 1, 0.01, true
            }
        case 69:
            switch disease_symptom {
                case 0: return 1, .9, 0.01, true
                case 1: return 4, .9, 0.01, true
                case 2: return 5, .9, 0.01, true
                case 3: return 6, .5, 0.01, true
                case 4: return 7, 1, 0.01, true
                case 5: return 10, .9, 0.01, true
                case 6: return 14, 1, 0.01, true
                case 7: return 33, 0, 0.01, true
                case 8: return 42, .5, 0.01, true
                case 9: return 59, 1, 0.01, true
            }
        case 70:
            switch disease_symptom {
                case 0: return 7, .5, 0.01, true
                case 1: return 33, 0, 0.01, true
                case 2: return 53, .2, 0.01, true
                case 3: return 59, .9, 0.01, true
                case 4: return 63, .5, 0.01, true
            }
        case 71:
            switch disease_symptom {
                case 0: return 6, .5, 0.01, true
                case 1: return 7, .8, 0.01, true
                case 2: return 14, .5, 0.01, true
                case 3: return 33, 0, 0.01, true
                case 4: return 58, 1, 0.01, true
                case 5: return 59, 1, 0.01, true
            }
        case 72:
            switch disease_symptom {
                case 0: return 2, .5, 0.01, true
                case 1: return 45, .6, 0.01, true
                case 2: return 58, .5, 0.01, true
                case 3: return 59, .99, 0.01, true
            }
        case 73:
            switch disease_symptom {
                case 0: return 33, .5, 0.01, true
                case 1: return 58, .9, 0.01, true
                case 2: return 59, 1, 0.01, true
            }
        case 74:
            switch disease_symptom {
                case 0: return 1, .5, 0.01, true
                case 1: return 33, .8, 0.01, true
                case 2: return 59, .9, 0.01, true
            }
        case 75:
            switch disease_symptom {
                case 0: return 1, .5, 0.01, true
                case 1: return 21, .8, 0.01, true
                case 2: return 22, .9, 0.01, true
                case 3: return 23, .9, 0.01, true
                case 4: return 38, .9, 0.01, true
                case 5: return 42, .8, 0.01, true
                case 6: return 45, .9, 0.01, true
                case 7: return 46, .8, 0.01, true
                case 8: return 47, .9, 0.01, true
                case 9: return 61, 0.00001, 0.01, true
                case 10: return 63, .3, 0.01, true
                case 11: return 67, .3, 0.01, true
            }
        case 76:
            switch disease_symptom {
                case 0: return 1, .5, 0.01, true
                case 1: return 60, .5, 0.01, true
                case 2: return 61, 0.0001, 0.01, true
                case 3: return 65, .99, 0.01, true
                case 4: return 67, 1, 0.01, true
            }
        case 77:
            switch disease_symptom {
                case 0: return 40, .5, 0.01, true
                case 1: return 41, .7, 0.005, true
                case 2: return 51, .6, 0.001, true
                case 3: return 55, .5, 0.01, true
                case 4: return 61, 0.0001, 0.01, true
            }
        case 78:
            switch disease_symptom {
                case 0: return 19, .4, 0.01, true
                case 1: return 37, .5, 0.01, true
                case 2: return 38, .8, 0.01, true
                case 3: return 57, .5, 0.01, true
            }
        case 79:
            switch disease_symptom {
                case 0: return 22, .5, 0.01, true
                case 1: return 53, .8, 0.01, true
                case 2: return 58, .7, 0.01, true
                case 3: return 62, .6, 0.01, true
                case 4: return 63, .99, 0.01, true
            }
        case 80:
            switch disease_symptom {
                case 0: return 2, .9, 0.01, true
                case 1: return 6, .9, 0.01, true
                case 2: return 7, .9, 0.01, true
                case 3: return 14, .9, 0.01, true
                case 4: return 44, .5, 0.001, true
                case 5: return 53, .8, 0.01, true
                case 6: return 59, .5, 0.01, true
                case 7: return 63, .8, 0.01, true
            }
        case 81:
            switch disease_symptom {
                case 0: return 7, .8, 0.01, true
                case 1: return 14, .8, 0.01, true
                case 2: return 22, .5, 0.01, true
                case 3: return 53, .8, 0.01, true
                case 4: return 58, .8, 0.01, true
                case 5: return 61, 0.001, 0.01, true
                case 6: return 63, .9, 0.01, true
            }
        case 82:
            switch disease_symptom {
                case 0: return 2, .8, 0.01, true
                case 1: return 7, .8, 0.01, true
                case 2: return 14, .9, 0.01, true
                case 3: return 15, .7, 0.01, true
                case 4: return 53, .6, 0.01, true
                case 5: return 63, .99, 0.01, true
            }
        case 83:
            switch disease_symptom {
                case 0: return 1, .9, 0.01, true
                case 1: return 50, .9, 0.01, true
                case 2: return 62, .5, 0.01, true
            }
        case 84:
            switch disease_symptom {
                case 0: return 27, .2, 0.01, true
                case 1: return 33, 1, 0.01, true
                case 2: return 47, .9, 0.01, true
                case 3: return 49, .2, 0.01, true
                case 4: return 50, .8, 0.01, true
                case 5: return 52, .8, .5, true
            }
        case 85:
            switch disease_symptom {
                case 0: return 6, .8, 0.01, true
                case 1: return 7, .8, 0.01, true
                case 2: return 14, .8, 0.01, true
                case 3: return 47, .1, 0.01, true
                case 4: return 58, 0.001, 0.01, true
                case 5: return 59, .5, 0.01, true
                case 6: return 63, .8, 0.01, true
            }
        case 86:
            switch disease_symptom {
                case 0: return 7, .5, 0.01, true
                case 1: return 64, .9, 0.01, true
                case 2: return 65, .9, 0.01, true
                case 3: return 66, .9, 0.01, true
            }
        case 87:
            switch disease_symptom {
                case 0: return 7, .6, 0.01, true
                case 1: return 40, .5, 0.01, true
                case 2: return 41, .5, 0.01, true
                case 3: return 61, 0.0001, 0.01, true
                case 4: return 64, .7, 0.01, true
            }
        case 88:
            switch disease_symptom {
                case 0: return 7, .3, 0.01, true
                case 1: return 41, .5, 0.01, true
                case 2: return 64, .9, 0.01, true
                case 3: return 65, .5, 0.01, true
                case 4: return 66, .5, 0.01, true
            }
        case 89:
            switch disease_symptom {
                case 0: return 1, .9, 0.01, true
                case 1: return 67, .9, 0.01, true
            }
        case 90:
            switch disease_symptom {
                case 0: return 7, .8, 0.01, true
                case 1: return 14, .8, 0.01, true
                case 2: return 16, .5, 0.01, true
                case 3: return 40, .5, 0.01, true
                case 4: return 41, .5, 0.01, true
                case 5: return 44, .5, 0.01, true
            }
    }
    return 0, 0, 0, false
}

// Return the question about the given symptom.
question :: proc(symptom : int) -> string {
    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)."
    }
    return ""
}

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

// Last modified 20250624T2035+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.

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

*/

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

package eee

import "../lib/anodino/src/par"
import "../lib/anodino/src/read"
import "core:fmt"
import "core:math/rand"
import "core:strconv"
import "core:strings"

user_input_string :: proc() -> string {
    PROMPT :: "> "
    fmt.print(PROMPT)
    return read.a_string() or_else ""
}

print_menu :: proc() {
    when DEBUG_LEVEL == 0 {
        par.whole("Comandos:")
    } else {
        par.whole("Comandos principales:")
    }
    par.whole("- Consultar")
    par.whole("- Finalizar")
    when DEBUG_LEVEL > 0 {
        par.whole("Comandos para depuración:")
        par.whole("- Probar (modo automático con respuestas aleatorias)")
        par.whole(fmt.tprintf("- Número de %v a %v (modo automático con respuesta única)", MIN_ANSWER, MAX_ANSWER))
    }
}

// Ask the user for permission to start a new consult; return `true` for yes
// and `false` for no.
ready :: proc() -> bool {
    for {
        print_menu()
        answer := strings.to_lower(user_input_string())
        switch {
            case strings.has_prefix("consultar", answer):
                mode = .Normal
                return true
            case strings.has_prefix("finalizar", answer):
                return false
            case strings.has_prefix("probar", answer):
                when DEBUG_LEVEL > 0 {
                    mode = .Random_Demo
                    return true
                }
            case :
                when DEBUG_LEVEL > 0 {
                    value_demo_mode : bool
                    demo_value, value_demo_mode = valid_answer(answer)
                    if value_demo_mode {
                        mode = .Value_Demo
                        return true
                    }
                }
        }
    }
    return false
}

press_enter :: proc() {
    fmt.println()
    par.whole("Pulsa la tecla «intro» para empezar.")
    user_input_string()
}

// Check the given user answer string; if it is valid, return its numerical
// value and `true`; otherwise return 0 and `false`.
valid_answer :: proc(answer : string) -> (int, bool) {
    switch len(answer) {
        case 1:
            if ! strings.contains("012345", answer) {
                return 0, false
            }
        case 2:
            if ! strings.contains("+-", strings.cut(answer, 0, 1)) {
                return 0, false
            }
            if ! strings.contains("012345", strings.cut(answer, 1, 1)) {
                return 0, false
            }
        case:
            return 0, false
    }
    return strconv.parse_int(answer)
}

// Prompt the user for a valid answer, check it and return it.
user_answer :: proc() -> int {
    answer_value : int
    for {
        par.whole(fmt.tprintf(
            "Responde con un número de %v a %v:",
            MIN_ANSWER, MAX_ANSWER)
        )
        par.whole(fmt.tprintf(
            "%v (no, nunca) … 0 … %v (sí, siempre)",
            MIN_ANSWER, MAX_ANSWER)
        )
        answer_value = valid_answer(user_input_string()) or_continue
        break
    }
    return answer_value
}

// Return a random number in the range `MIN_ANSWER ..= MAX_ANSWER`.
random_answer :: proc() -> int {

    return rand.int_max(MAX_ANSWER - MIN_ANSWER + 1) + MIN_ANSWER

}

// VERSION.odin
//
// This file is part of Experto en enfermedades (Expert on diseases)

// Last modified 20250624T2035+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.

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

*/

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

package eee

VERSION :: "0.1.0-dev.0.28.2+20250626T0103CEST"

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 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.
Experto en enfermedades (versión en D)
Sistema experto sobre enfermedades, escrito en D.