sepi_neigh_merge.pl 3.27 KB
Newer Older
1 2 3 4 5 6 7 8
:- module(
  sepi_neigh_merge,
  [
    % Commands
    merge_neigh/3
  ]
).

BARGAIN Orianne's avatar
BARGAIN Orianne committed
9

10 11 12 13
:- use_module(biocham).
:- use_module(sepi_infos).
:- use_module(sepi_util).

BARGAIN Orianne's avatar
BARGAIN Orianne committed
14

15 16
%%  two-neighbours local merge restriction
%%  Optional, used with option(merge_restriction: neigh)
17

BARGAIN Orianne's avatar
BARGAIN Orianne committed
18

19 20 21 22 23 24 25
%! merge_neigh(+G1, +G2, +Stream)
%
% write strict two neighbours merge restriction
%
% @arg G1     graph 1 [NbVertexe, NbSpecie, EdgesList, Id]
% @arg G2     graph 2 [NbVertexe, NbSpecie, EdgesList, Id]
% @arg Stream Stream for the CNF file
26
merge_neigh(G1, G2, Stream):-
27 28
  assert_G1(G1),
  assert(arc_G1(0, 0)),
29 30 31
  assert_neighbours(G1),
  debug(sepi, "done listing neighbours", []),
  neigh_clauses_assert(G1, G2, Stream),
BARGAIN Orianne's avatar
BARGAIN Orianne committed
32
  debug(sepi, "done writing 2 neighbours clauses", []),
33 34 35 36
  retractall(neigh(_, _)),
  retractall(arc_G1(_, _)).


37 38 39 40 41
%! assert_G1(+G1)
%
% Asserts a fact arc_G1(A, B) for each arc to optimise the merge restriction
%
% @arg G1     graph 1 [NbVertexe, NbSpecie, EdgesList, Id]
42 43 44 45 46 47
assert_G1(G1):-
  G1 = [_, _, E1, _],
  forall(
    member((A, B), E1),
    assert(arc_G1(A, B))
  ).
48

BARGAIN Orianne's avatar
BARGAIN Orianne committed
49

50 51 52 53 54
%! assert_neighbours(+G1)
%
% Asserts a fact neigh(A,B) when A and B are two neighbours 
%
% @arg G1     graph 1 [NbVertexe, NbSpecie, EdgesList, Id]
55
assert_neighbours(G1):-
56
  G1 = [N1, _, _, _],
57 58 59
  N1_1 is N1 - 1,
  numlist(0,N1_1,Vertex_G1),
  forall(
BARGAIN Orianne's avatar
BARGAIN Orianne committed
60
    member(A, Vertex_G1),
61
    (
BARGAIN Orianne's avatar
BARGAIN Orianne committed
62
      forall(
63
        (
64
          arc_G1(A, B)
65
        ;
66
          arc_G1(B, A)
67 68
        ),
        (
BARGAIN Orianne's avatar
BARGAIN Orianne committed
69 70
          forall(
            (
71
              arc_G1(C, B)
BARGAIN Orianne's avatar
BARGAIN Orianne committed
72
            ;
73
              arc_G1(B, C)
BARGAIN Orianne's avatar
BARGAIN Orianne committed
74 75 76
            ),
            assert(neigh(A,C))
          )
77 78 79 80 81
        )
      )
    )
  ).

BARGAIN Orianne's avatar
BARGAIN Orianne committed
82

83 84 85 86 87 88 89
%! neigh_clauses_assert(+G1, +G2, +Stream)
%
% Search for all non two neighbours vertices
%
% @arg G1     graph 1 [NbVertexe, NbSpecie, EdgesList, Id]
% @arg G2     graph 2 [NbVertexe, NbSpecie, EdgesList, Id]
% @arg Stream Stream for the CNF file
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
neigh_clauses_assert(G1, G2, Stream):-
  G1 = [N1, _, _, _],
  N1_1 is N1 - 1,
  numlist(0,N1_1,Vertex_G1),
  forall(
    (
      member(A, Vertex_G1),
      member(B, Vertex_G1)
    ),
    (
      (
        not(neigh(A,B)),
        not(neigh(B,A)),
        not(A is B)
      )
    ->
      debug(sepi, "A ~w B ~w not neigh", [A, B]),
      neigh_clauses_not_neigh_assert(A, B, N1, G2, Stream)
    ;
      debug(sepi, "A ~w B ~w neigh", [A, B])
    )
  ).
112

113 114 115 116 117 118 119 120 121 122 123 124

%! neigh_clauses_not_neigh_assert(+A, +B, +N1, +G2, +Stream)
%
% mu is a morphism from an initial graph G1 to an image graph G2
% A and B are not two-neighbours, they can't have the same image through mu
% writes '-mu(a)=u or -mu(b)=y' for all y in G2
%
% @arg A      First non neighbours vertex
% @arg B      Second non neighbours vertex
% @arg N1     Number of vertices in graph 1
% @arg G2     graph 2 [NbVertexe, NbSpecie, EdgesList, Id]
% @arg Stream Stream for the CNF file
BARGAIN Orianne's avatar
BARGAIN Orianne committed
125
neigh_clauses_not_neigh_assert(A, B, N1, G2, Stream):-
126 127 128 129 130 131 132 133 134 135
  G2 = [N2, _, _, _],
  N2_1 is N2 - 1,
  numlist(0,N2_1,Vertex_G2),
  forall(
    (
      member(Y, Vertex_G2)
    ),
    (
      m_ij(A, Y, N2, May),
      m_ij(B, Y, N2, Mby),
BARGAIN Orianne's avatar
BARGAIN Orianne committed
136
      get_option(extremal_sepi, Extremal_sepi),
137
      (
BARGAIN Orianne's avatar
BARGAIN Orianne committed
138
        Extremal_sepi \= no
139 140 141 142 143 144 145 146 147
      ->
        Top is N1 + 1,
        format(Stream, "~d -~d -~d 0~n", [Top, May, Mby])
      ;
        format(Stream, "-~d -~d 0~n", [May, Mby])
      ),
      debug(merge, "A ~w B ~w Y ~w", [A, B, Y])
    )
  ).