```    1:- module(lazymath, [ add/3, sub/3, mul/3, max/3, min/3, stoch/2, exp/2, log/2, lse/2, pow/3, log_stoch/2
2                    , patient/3, patient/4]).```

# Multimoded arithmetic operations

This module is here mostly because there are some numerical problems with library(clpr). */
```    8:- use_module(library(math), [stoch/3]).    9:- use_module(library(callutils)).   10:- use_module(library(insist)).   11
12% lazy arithmetic predicates
13max(X,Y,Z) :- when(ground(X-Y), Z is max(X,Y)).
14min(X,Y,Z) :- when(ground(X-Y), Z is min(X,Y)).
15add(X,Y,Z) :- when(ground(X-Y), Z is X+Y).
16sub(X,Y,Z) :- when(ground(X-Y), Z is Y-X).
17mul(X,Y,Z) :- when(ground(X-Y), Z is X*Y).
18stoch(X,Y) :- when(ground(X),   insist(stoch(X,Y,_))).
19log(X,Y)   :- when(ground(X),   Y is log(X)).
20exp(X,Y)   :- when(ground(X),   Y is exp(X)).
21pow(1,X,X) :- !.
22pow(B,X,Y) :- when(ground(X), Y is X^B).
23log_stoch(X,Y) :- when(ground(X), log_stoch_strict(X,Y)).
24
25log_stoch_strict([_],[0.0]) :- !.
26log_stoch_strict(LogWeights,LogProbs) :-
27   log_sum_exp(LogWeights, LogTotal),
28   maplist((math:sub(LogTotal)), LogWeights, LogProbs).
29
30lse(Xs,Z) :- when(ground(Xs), log_sum_exp(Xs,Z)).
31
32log_sum_exp([X],X) :- !.
33log_sum_exp(Xs,Y) :-
34   max_list(Xs,M),