% -----------------
% Quantum Darwinism
% -----------------
%
% Quantum Darwinism is a theory proposing that the classical world
% emerges from the quantum world through a natural selection-like
% process, where certain quantum states proliferate by imprinting
% themselves redundantly into the environment, making them observable
% and objective.
%
% # original code generated by ChatGPT
%
% Core Concepts Modeled
% - state(ID, Amplitude, PointerFlag)
% - entangled(State1, State2)
% - decohered(State, Flag)
% - observer(Name)
% - measured(Observer, State)
% - agrees(Observer1, Observer2)
% - disagrees(Observer1, Observer2)
% - evolves_from(NewState, OldState)

:- use_module(library(gensym)).

:- dynamic(state/2).
:- dynamic(entangled/2).
:- dynamic(evolves_from/2).

% --- Initial Quantum States ---
state([state1, 0.9], true).
state([state2, 0.4], false).
state([state3, 0.9], true).
state([state4, 0.4], false).

% --- Entanglement ---
entangled(state1, state3).
entangled(state2, state4).

% --- Symmetric wrapper for entanglement ---
linked(A, B) :- entangled(A, B).
linked(A, B) :- entangled(B, A).

% --- Decoherence: pointer states decohere ---
decohered(State, true) :-
    state([State, _], true).

% --- Observers ---
observer(alice).
observer(bob).

% --- Measurements ---
measured(alice, state1).
measured(bob, state3).

% --- Amplitude lookup ---
amplitude(Observer, Amp) :-
    measured(Observer, State),
    state([State, Amp], _).

% --- Agreement logic ---
agrees(O1, O2) :-
    O1 \= O2,
    measured(O1, S1),
    measured(O2, S2),
    linked(S1, S2),
    amplitude(O1, A),
    amplitude(O2, A),
    decohered(S1, true),
    decohered(S2, true).

agrees(O1, O2) :-
    O1 \= O2,
    measured(O1, S1),
    measured(O2, S2),
    linked(S1, S2),
    amplitude(O1, A1),
    amplitude(O2, A2),
    A1 \= A2.

% === NEW: Quantum State Evolution ===
% evolve(+OldState, -NewState).
evolve(OldState, NewState) :-
    state([OldState, Amp], Pointer),
    gensym(state, NewState),
    assertz(state([NewState, Amp], Pointer)),
    assertz(evolves_from(NewState, OldState)),
    % propagate entanglement
    forall(entangled(OldState, Other),
           assertz(entangled(NewState, Other))),
    format("% 🌱 New state created: ~w from ~w~n", [NewState, OldState]).

% query
true :+ evolve(state1, _).
true :+ retract(state([state3, 0.9], true)), assertz(state([state3, 0.4], true)), agrees(alice, bob).
true :+ measured(alice, _), amplitude(alice, _).
