function bnet = mk_bnet_from_noisyor(inhibit)
% MK_BNET_FOR_NOR Make a mini Bayes net representing a noisy-or gate.
% bnet = mk_bnet_for_nor(inhibit)
%
% To learn the parameters of a noisy-or gate, we follow the method
% in "Learning Causal interaction models", Meek and Heckerman, UAI 97.
%
% We convert the original family
%    C1..Cp
%     \  /
%       E
% (where C_i is the i'th cause and E is the effect) to a new network
%    C1(1)     Cp(p)
%     |          |
%    X1(p+1)   X2(2p)
%     \        /
%       E(2p+1)
% where Xi is a noisy version of Ci and E is a deterministic OR of the Xis.
% (The number of each node is shown in parentheses.)
% Then the desired inhibition probabilities are
%   qi defeq Pr(X_i = off | C_i = on) approx N(C_i=on, X_i = off) / N(C_i=on).
% We can learn the qi's using standard techniques, since the Xis are tabular nodes.
%
% Note that this net is a polytree, but we don't exploit this directly.

np = length(inhibit); % num. parents (including leak)
N = 2*np+1;
Cs = 1:np;
Xs = np+1:2*np;
E = 2*np+1;
dag = zeros(N);
for i=1:np
  dag(Cs(i), Xs(i)) = 1;
end
dag(Xs,E) = 1;
bnet = mk_bnet(dag, twos(1,N), 1:N);
prior = 0;
for i=1:np
  % We would make the Cs input nodes, except that we have to add soft evidence to them.
  bnet.bnodes{i} = mk_tabular_node(bnet, i, prior);
  bnet.bnodes{i}.CPT = [0.5 0.5]'; % uniform prior
  bnet.bnodes{i}.adjustable = 0;
end
for i=1:np
  x = Xs(i);
  bnet.bnodes{x} = mk_tabular_node(bnet, x, prior);
  q = inhibit(i);
  % CPT =   Xoff  Xon
  %    Coff  1.0   0
  %    Con   q    1-q
  bnet.bnodes{x}.CPT = [1 0; q  1-q];
  % Strictly speaking, we should declare the first row of this table non-adjustable.
end
bnet.bnodes{E} = mk_tabular_node(bnet, E, 0);
bnet.bnodes{E}.CPT = mk_CPT_from_deterministic_or(np);
bnet.bnodes{E}.adjustable = 0;

bnet = compile_params(bnet);

