Preguntas que se pueden ejecutar
Cada ejemplo toma una pregunta real de la filosofía de la mente y la convierte en un mundo, o en un conjunto de mundos que comparar. El código usa la API prevista, así que muestra la idea más que un programa terminado.
1. Emergentismo frente a inmersionismo
El emergentismo dice que la experiencia surge de la materia cuando esta se organiza de cierta manera. El inmersionismo dice lo contrario: las experiencias abstractas ya existen, y un individuo aparece cuando un cuerpo «sintoniza» con una combinación de ellas. ¿Son realmente teorías distintas o dos descripciones del mismo mundo?
import gaiabasic as gb
def make(sentience):
w = gb.World("symmetry", seed=7)
w.sentience = sentience
w.populate(gb.species.Fish, n=300)
return w
emergent = make(gb.Emergentism(threshold=gb.Complexity(min_neurons=5_000)))
immersion = make(gb.Immersionism(receiver=gb.Complexity(min_neurons=5_000)))
reports = [w.run(steps=20_000) for w in (emergent, immersion)]
print(gb.compare(reports).differences())
Si la comparación no muestra diferencias observables, la elección entre ambas teorías no puede decidirse solo por el comportamiento. Eso ya es en sí un resultado útil.
2. ¿Útil o inevitable?
Si la sintiencia es un mero subproducto, como el ruido del motor de un avión, la evolución no puede seleccionarla. Si es útil, debe cambiar el comportamiento, y en algún punto la materia debería comportarse de formas que la física por sí sola no predice. GaiaBasic cuenta esas «rupturas de reglas».
for causal in (False, True):
w = gb.World(f"causal={causal}", seed=3)
w.ontology = gb.Dualism(gb.Matter, gb.Experience)
w.sentience = gb.Emergentism(causal=causal)
w.populate(gb.species.Mouse, n=500)
r = w.run(steps=30_000)
print(causal, r.rule_breaks.count, r.selection_pressure("sentience"))
Relacionado: el proyecto de investigación ¿Útil o inevitable?.
3. P-zombis y motivación
Un zombi filosófico se comporta como nosotros pero no siente nada. Cuatro configuraciones cubren las posiciones principales: sintiente o no, y resultados distintos o idénticos. GaiaBasic ejecuta la matriz completa y marca las celdas que resultan incoherentes. Una celda incoherente es un resultado válido, no un fallo.
matrix = gb.Grid(
sentient=[True, False],
affects_outcome=[True, False],
)
for cfg in matrix:
w = gb.World(str(cfg))
w.sentience = gb.Emergentism(enabled=cfg.sentient, causal=cfg.affects_outcome)
w.populate(gb.species.Mammal, n=200)
matrix.record(cfg, w.run(steps=10_000))
matrix.table(columns=["coherence", "fitness", "rule_breaks"])
4. Gradientes de felicidad
¿Podrían organismos motivados solo por más o menos placer desenvolverse tan bien como organismos impulsados por el dolor y el placer? La idea procede de David Pearce. Dos poblaciones comparten un entorno; solo difiere su modelo de valencia.
w = gb.World("bliss", seed=11)
w.populate(gb.species.Rabbit, n=200, tag="pain+pleasure",
valence=gb.Valence.full()) # rango -1 .. +1
w.populate(gb.species.Rabbit, n=200, tag="pleasure-only",
valence=gb.Valence.gradient(0.2, 1.0)) # nunca por debajo de 0.2
w.environment.add(gb.hazards.Predators(), gb.hazards.Cold())
r = w.run(steps=40_000)
r.survival_by("tag").plot()
5. ¿Hay más sufrimiento que disfrute en la naturaleza?
La respuesta depende de suposiciones ocultas: ¿cuenta una vida corta tanto como una larga? ¿Aumenta la intensidad con el tamaño del cerebro? ¿Sienten algo las numerosas crías de las especies estrategas de la r antes de morir? GaiaBasic convierte cada suposición en un parámetro, para que podamos ver de cuáles depende la respuesta.
study = gb.Sweep(
intensity_scale=["flat", "neurons", "sqrt_neurons"],
newborn_sentience=[True, False],
suffering_when_dying=["full", "reduced"],
)
for cfg in study:
w = gb.presets.Ecosystem(r_strategists=0.9, k_strategists=0.1)
w.sentience = gb.Emergentism(intensity_scale=cfg.intensity_scale,
from_birth=cfg.newborn_sentience)
study.record(cfg, w.run(steps=100_000).valence_balance)
study.sensitivity() # ¿qué suposición cambia el signo del resultado?
6. La evolución del placer
Los agentes tienen reglas de comportamiento y un generador de experiencias. La experiencia puede ignorarse (eliminativismo), estar presente pero sin efecto (emergencia epifenoménica) o ser causal (dualismo). ¿Pueden evolucionar patrones de placer sexual, como el orgasmo único y el múltiple, y desaparecen cuando se eliminan las reglas que los vinculan a la reproducción?
for model in (gb.Eliminativism(), gb.Epiphenomenalism(), gb.Dualism.interactive()):
w = gb.World("pleasure", seed=5)
w.sentience = model
w.populate(gb.species.SexualAgent, n=1_000,
rules=[gb.rules.ApproachPleasure(), gb.rules.StopWhenSatisfied()])
r = w.run(steps=200_000)
print(type(model).__name__, r.distribution("orgasm_pattern"))
7. Identidad y trascendencia
El mismo mundo puede contarse de tres maneras. Con el individualismo cerrado, cada animal es un sujeto. Con el individualismo vacío, cada instante es un sujeto nuevo. Con el individualismo abierto, un único sujeto tiene todas las experiencias. Los operadores de trascendencia permiten copiar o mover identidades, por ejemplo a una vida después de la muerte.
w = gb.World("identities", seed=2)
w.populate(gb.species.Bird, n=100)
w.on_death(lambda being: gb.move(being.identity, to=w.realm("afterlife")))
for model in (gb.ClosedIndividualism(), gb.EmptyIndividualism(), gb.OpenIndividualism()):
w.identity = model
r = w.run(steps=10_000, replay=True) # misma historia física, contada de nuevo
print(type(model).__name__, r.subjects, r.max_suffering_per_subject)
8. Teorías de la sintiencia que evolucionan
En lugar de poner a prueba solo las teorías que nos parecen intuitivas, GaiaBasic puede explorar el espacio de teorías con un algoritmo genético. Cada candidata es un punto del mapa de teorías A–I más unos parámetros. Su aptitud es su coherencia y su ajuste a las observaciones. Definir bien esa función de aptitud es la parte más difícil, y la más interesante.
search = gb.TheorySearch(
space=gb.theory.MAP_AXES, # ejes A..I y sus opciones
population=100,
fitness=gb.fitness.coherence + gb.fitness.empirical_fit,
)
best = search.evolve(generations=10_000)
for theory in best[:5]:
print(theory.map_code(), theory.score)