function pred = load_predicates(plant) % LOAD_PREDICATES Read predicates.json and resolve rhs_expr into numbers. % % Each halfspace entry in the JSON stores rhs_expr as a string because % several of the bounds are defined relative to plant-derived constants % (T_c0, T_cold0, T_standby). We evaluate those expressions here in a % controlled workspace that exposes exactly those names plus the % derived offsets from the JSON. % % Returns a struct `pred` with one field per predicate, each a struct % holding an n_hs x 10 matrix A_poly and an n_hs x 1 vector b_poly such % that the predicate is { x : A_poly * x <= b_poly }. % % Also returns: % pred.constants - a struct with T_c0, T_cold0, T_f0, T_standby, etc. % % Usage: % plant = pke_params(); % pred = load_predicates(plant); % A = pred.t_avg_in_range.A_poly; % 2 x 10 % b = pred.t_avg_in_range.b_poly; % 2 x 1 % is_in = all(A * x <= b); % predicate check on state x here = fileparts(mfilename('fullpath')); raw = fileread(fullfile(here, 'predicates.json')); J = jsondecode(raw); % --- Constants used in rhs_expr evaluations --- T_c0 = plant.T_c0; %#ok T_f0 = plant.T_f0; %#ok T_cold0 = plant.T_cold0; %#ok T_standby_offset_C = J.derived.T_standby_offset_C; T_standby = T_c0 + T_standby_offset_C; %#ok pred.constants = struct( ... 'T_c0', plant.T_c0, ... 'T_f0', plant.T_f0, ... 'T_cold0', plant.T_cold0, ... 'T_standby', T_standby, ... 'T_standby_offset_C', T_standby_offset_C, ... 'T_standby_offset_F', J.derived.T_standby_offset_F, ... 't_avg_in_range_halfwidth_C', J.derived.t_avg_in_range_halfwidth_C, ... 'p_above_crit_threshold_n', J.derived.p_above_crit_threshold_n); % --- Loop over predicates, build A/b matrices --- names = fieldnames(J.predicates); for k = 1:numel(names) name = names{k}; entry = J.predicates.(name); hs_list = entry.halfspaces; % jsondecode returns a struct array if entries are uniform, else cell. if iscell(hs_list) n_hs = numel(hs_list); get_hs = @(i) hs_list{i}; else n_hs = numel(hs_list); get_hs = @(i) hs_list(i); end A_poly = zeros(n_hs, 10); b_poly = zeros(n_hs, 1); for i = 1:n_hs hs = get_hs(i); A_poly(i, hs.state_index) = hs.coeff; b_poly(i) = eval(hs.rhs_expr); %#ok end pred.(name).A_poly = A_poly; pred.(name).b_poly = b_poly; pred.(name).meaning = entry.meaning; end end