# fórmulas serão listas: primeiro o conectivo principal (se houver) depois a subfórmula principal da esquerda, depois (se houve) a da direita

# exemplo:
fi = ("conj", ("Hugo está de camiseta",), ("neg", ("Hugo está de fraque",)))

def é_atômica(fórmula):
    return len(fórmula) == 1

def é_negação(fórmula):
    return (not é_atômica(fórmula)) and fórmula[0] == "neg"

def sub(fórmula):
    if é_atômica(fórmula):
        return {fórmula}
    if é_negação(fórmula):
        return {fórmula}.union(sub(fórmula[1]))
    return {fórmula}.union(sub(fórmula[1])).union(sub(fórmula[2]))

def compr(fórmula):
    if é_atômica(fórmula):
        return 1
    if é_negação(fórmula):
        return 3 + compr(fórmula[1])
    return 3 + compr(fórmula[1]) + compr(fórmula[2])

def ocorre(letra, fórmula, posição):
    if é_atômica(fórmula):
        return fórmula == (letra,) and posição == 0

    if é_negação(fórmula):
        return ocorre(letra, fórmula[1], posição - 2)

    return ocorre(letra,fórmula[1],posição - 1) or ocorre(letra, fórmula[2], posição - 2 - compr(fórmula[1]))

def humana(fórmula):
    """Retorna uma string legível representando a fórmula"""
    if é_atômica(fórmula):
        return fórmula[0]
    if é_negação(fórmula):
        return f"(¬ {humana(fórmula[1])})"
    match fórmula[0]:
        case "conj": conectivo_humana = "∧"
        case "disj": conectivo_humana = "∨"
        case "impl": conectivo_humana = "⟶"
        case "biimpl": conectivo_humana = "⟷"
    return f"({humana(fórmula[1])} {conectivo_humana} {humana(fórmula[2])})"
