1  % herramientas para el manejo de 'features' en inglés
  2  % gabriel@ranchonotorious.org
  3
  4  % cargar segments
  5  init
  6          :-
  7                  consult('features.pro')
  8          ,       write_nl_list([
  9                          'herramientas para manejo de ''features'' en inglés'
 10                  ,       'predicados:'
 11                  ,       '       display_segment(Segment+).'
 12                  ,       '       find_segment(Segment+).'
 13                  ,       '       find_all_segments(Feature_list+, List-).'
 14                  ,       '       compare_segments(Segment_list+, Common_features-).'
 15                  ,       '       contrast_segments(Segment_1+, Segment_2+).'
 16                  ,       '       segment_superset(Segment_list+, List_superset-).'
 17                  ,       '       segments_to_features(Segment_list+, Lists_of_features-).'
 18                  ])
 19
 20  .
 21
 22  % sobre los segmentos
 23  compare_segments(Segment_list, Common_features)
 24          :-
 25                  segments_to_features(Segment_list, Lists_of_features)
 26          ,       common_elements_from_list(Lists_of_features, Common_features)
 27          .
 28
 29  contrast_segments(S1, S2)
 30          :-
 31                  segments_to_features([S1, S2], [F1|[F2_h|[]]])
 32          ,       diff_elements(F1, F2_h, Diff_1)
 33          ,       diff_elements(F2_h, F1, Diff_2)
 34
 35          ,       write(S1)
 36          ,       write(':')
 37          ,       write(Diff_1)
 38          ,       nl
 39          ,       write(S2)
 40          ,       write(':')
 41          ,       write(Diff_2)
 42          .
 43
 44  segment_superset(Segment_list, List_superset)
 45          :-
 46                  compare_segments(Segment_list, Common_features)
 47          ,       find_all_segments(Common_features, List_superset)
 48          .
 49
 50  display_segment(Segment)
 51          :-
 52                  segment(Segment, Features)
 53          ,       write_nl_list([Segment|Features])
 54          .
 55
 56  find_segment(Feature_list, Segment)
 57          :-
 58                  segment(Segment, Features)
 59          ,       all_are_members(Feature_list, Features)
 60          .
 61
 62  find_all_segments(Feature_list, List)
 63          :-
 64                  bagof(Segment, find_segment(Feature_list, Segment), List)
 65          .
 66
 67  segments_to_features(Segment_list, Lists_of_features)
 68          :-
 69                  segments_to_features(Segment_list,[],Lists_of_features)
 70          .
 71
 72  segments_to_features([],Acumulator, Acumulator).
 73
 74  segments_to_features([H|List_of_segments], Acumulator, Lists_of_features)
 75          :-
 76                  segment(H,Features)
 77          ,       segments_to_features(List_of_segments, [Features|Acumulator],Lists_of_features)
 78          .
 79
 80
 81  % manipulación de listas
 82  member(Element, [Element|_]).
 83  member(Element, [_|List])       
 84          :-
 85                  member(Element, List)
 86          .
 87
 88  non_member(Element, List)
 89          :-
 90                  not(member(Element, List))
 91          .
 92
 93  all_are_members([], _).
 94  all_are_members([Next|List], Set)
 95          :-
 96                  member(Next, Set)
 97          ,       all_are_members(List, Set)
 98          .
 99
100  % common_elements /2, 
101  common_elements(List_1,List_2,Common)
102          :-
103                  common_elements(List_1, List_2, [], Common)
104          .
105
106  common_elements([],_,[]).
107  common_elements(_,[],[]).
108
109  common_elements([L1_h|L1_t], L2, Acumulator, Common)
110          :-
111                  member(L1_h, L2)
112          ,       common_elements(L1_t, L2, [L1_h|Acumulator], Common)
113          .
114
115  common_elements([L1_h|L1_t], L2, Acumulator, Common)
116          :-
117                  non_member(L1_h, L2)
118          ,       common_elements(L1_t, L2, Acumulator, Common)
119          .
120
121  common_elements([L_i|[]], L2, Acumulator, [L_i|Acumulator])
122          :-
123                  member(L_i, L2)
124          .
125
126  common_elements([L_i|[]], L2, Acumulator, Acumulator)
127          :-
128                  non_member(L_i, L2)
129          .
130
131  diff_elements(L1, L2, Diff)
132          :-
133                  diff_elements(L1, L2, [], Diff)
134          .
135
136  diff_elements([Item|[]], L2, Acumulator, [Item|Acumulator])
137          :-
138                  non_member(Item, L2)
139          .
140
141  diff_elements([Item|[]], L2, Acumulator, Acumulator)
142          :-
143                  member(Item, L2)
144          .
145
146  diff_elements([L1_h|L1_t], L2, Acumulator, Diff)
147          :-
148                  non_member(L1_h, L2)
149          ,       diff_elements(L1_t, L2, [L1_h|Acumulator], Diff)
150          .
151
152  diff_elements([L1_h|L1_t], L2, Acumulator, Diff)
153          :-
154                  member(L1_h, L2)
155          ,       diff_elements(L1_t, L2, Acumulator, Diff)
156          .
157
158  % common_elements_from_list(List_of_lists, Common).
159  common_elements_from_list([[H|T]], [H|T]).
160  common_elements_from_list([[]], []).
161  common_elements_from_list([[H1|T1],[H2|T2]|Tail],Common)
162          :-
163                  common_elements([H1|T1],[H2|T2], Partial)
164          ,       common_elements_from_list([Partial|Tail], Common)
165          .
166
167  % output
168  write_nl_list([]).
169  write_nl_list([Item|Remainders])
170          :-
171                  write(Item)
172          ,       nl
173          ,       write_nl_list(Remainders)
174          .
175
176  % vim:filetype=prolog