%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Problema 2: Interferencia de haplotipos.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Ulises Pastor Díaz.
% Lógica computacional.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Descripción del problema: Dado un conjunto G = {g_1,...,g_m} de
% genotipos, cada uno con n entradas, y un entero positivo k, determinar
% si existe una colección H de como mucho k haplotipos que explica G.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%% Parte 1: Construcción de los haplotipos.
% Tenemos 2m haplotipos.
haplo(1..2*M) :- M = #count{I : geno(I)}.
% Si tenemos g(i,j) = 0 o 1 asignamos o no respectivamente h(2i-,j) y h(2i,j).
h(2*I-1,J) :- g(I,J,1).
h(2*I,J) :- g(I,J,1).
:- h(2*I-1,J), g(I,J,0).
:- h(2*I,J), g(I,J,0).
% Si g(i,j) = 2, entonces sólo tenemos una de las dos posibilidades.
h(2*I-1,J) :- g(I,J,2), not h(2*I,J).
h(2*I,J) :- g(I,J,2), not h(2*I-1,J).
% 1 {h(2*I,J),h(2*I-1,J)} 1 :- g(I,J,2).
%% Parte 2: Encontrar los haplotipos representativos.
% Definir si dos haplotipos son el mismo.
{samehaplo(A,B)} :- haplo(A), haplo(B), A < B.
:- samehaplo(A,B), haplo(A), haplo(B), A < B, site(S), h(A,S), not h(B,S).
:- samehaplo(A,B), haplo(A), haplo(B), A < B, site(S), h(B,S), not h(A,S).
% Haplotipos repetidos.
repe(B) :- haplo(A;B), A < B, samehaplo(A,B).
% Haplotipos representativos.
repre(A) :- haplo(A), not repe(A).
%% Parte 3: Representación.
#show h/2.
#show repre/1.
%% Parte 4: Optimización. --opt-mode=optN
% num_haplo(N) :- N = #count{A: repre(A)}.
#minimize{1,A : repre(A)}.
%% Parte 5: Problema de decisión.
% #const k = 3.
% :- k < N, num_haplo(N).