Usually, we express hard constraint using potential, as it effectively cut out some part of the parameter space.

In this case, you can do it in a similar way:

```
with pm.Model() as model:
inv_b0 = pm.Flat('inv_b0')
b1 = pm.Flat('b1')
b0b1 = pm.Deterministic('b1/b0', b1*inv_b0)
pm.Potential('constraint', pm.Normal.dist(5., 1.).logp(b0b1))
trace = pm.sample()
pm.traceplot(trace, compact=True);
```

However, this model is unidentifiable as is, since you can have `b0*, b1* = k*b0, k*b1`

and still have `b1* / b0* == b1 / b0`

. You would need stronger prior on b0 and b1 to make it work nicely.

Also, note that the model above is expressing prior knowledge of the ratio, it’s NOT the same as constraint (i.e., the condition that the posterior of the parameter also satisfy). To express this as constraint is a bit more difficult, I would go with something like:

```
mu, sigma = 5., 5.
rand_stm = tt.shared_randomstreams.RandomStreams()
with pm.Model() as model:
b0 = pm.Normal('b0')
b1_div_b0 = pm.Deterministic('b1/b0', rand_stm.normal(avg=mu, std=sigma))
b1 = pm.Deterministic('b1', b1_div_b0*b0)
# pm.Potential('b1_prior', pm.Normal.dist(5., 2.).logp(b1))
trace = pm.sample()
pm.traceplot(trace, compact=True);
```

Note that now you actually have `b1 / b0 ~ Normal(mu, sigma)`

even for the posterior.