From 6843cffe91cdf78275b57b842636456bbdc85994 Mon Sep 17 00:00:00 2001 From: Alexandre Donze Date: Thu, 24 Sep 2020 11:01:19 +0200 Subject: [PATCH] 1.8.0 --- @STL_Formula/STL_Break.m | 38 ++- @STL_Formula/STL_EvalThom.m | 67 ++++- @STL_Formula/STL_EvalThom_Gen.m | 57 +++- @STL_Formula/STL_EvalThom_Gen_Rob.m | 58 +++- @STL_Formula/STL_ExtractSignals.m | 4 +- @STL_Formula/STL_Formula.m | 58 +++- @STL_Formula/disp.m | 44 ++- @STL_Formula/private/RobustAnd.mexmaci64 | Bin 0 -> 71460 bytes @STL_Formula/private/RobustAnd.mexw64 | Bin 17920 -> 17920 bytes @STL_Formula/private/RobustAndn.mexmaci64 | Bin 0 -> 71524 bytes @STL_Formula/private/RobustAndn.mexw64 | Bin 18432 -> 18432 bytes @STL_Formula/private/RobustAvEvLeft.mexmaci64 | Bin 0 -> 71500 bytes @STL_Formula/private/RobustAvEvLeft.mexw64 | Bin 34816 -> 34816 bytes .../private/RobustAvEvRight.mexmaci64 | Bin 0 -> 71500 bytes @STL_Formula/private/RobustAvEvRight.mexw64 | Bin 35328 -> 34816 bytes @STL_Formula/private/RobustEv.mexmaci64 | Bin 0 -> 71396 bytes @STL_Formula/private/RobustEv.mexw64 | Bin 30208 -> 30208 bytes @STL_Formula/private/RobustOr.mexmaci64 | Bin 0 -> 71460 bytes @STL_Formula/private/RobustOr.mexw64 | Bin 17920 -> 17920 bytes @STL_Formula/private/RobustUntil.mexmaci64 | Bin 0 -> 71396 bytes @STL_Formula/private/RobustUntil.mexw64 | Bin 41472 -> 41472 bytes @STL_Formula/private/lemire_engine.mexmaci64 | Bin 0 -> 17152 bytes @STL_Formula/private/lemire_engine.mexw64 | Bin 16384 -> 16384 bytes .../private/lemire_nd_engine.mexmaci64 | Bin 0 -> 21444 bytes @STL_Formula/private/lemire_nd_engine.mexw64 | Bin 21504 -> 19456 bytes .../private/lemire_nd_maxengine.mexmaci64 | Bin 0 -> 21500 bytes .../private/lemire_nd_maxengine.mexw64 | Bin 27136 -> 27136 bytes .../private/lemire_nd_minengine.mexmaci64 | Bin 0 -> 21500 bytes .../private/lemire_nd_minengine.mexw64 | Bin 27136 -> 27136 bytes @STL_Formula/private/lim_inf.mexmaci64 | Bin 0 -> 8784 bytes @STL_Formula/private/lim_inf.mexw64 | Bin 8192 -> 8192 bytes @STL_Formula/private/lim_inf_indx.mexmaci64 | Bin 0 -> 8784 bytes @STL_Formula/private/lim_inf_indx.mexw64 | Bin 7680 -> 8192 bytes @STL_Formula/private/lim_inf_inv.mexmaci64 | Bin 0 -> 8784 bytes @STL_Formula/private/lim_inf_inv.mexw64 | Bin 7680 -> 8192 bytes .../private/src/robusthom/CompileRobusthom.m | 2 +- .../private/src/robusthom/RobustAvEvRight.cpp | 2 +- @STL_Formula/private/until_inf.mexmaci64 | Bin 0 -> 8752 bytes @STL_Formula/private/until_inf.mexw64 | Bin 9728 -> 9728 bytes @STL_Formula/set_in_signal_names.m | 96 +++--- @STL_Formula/set_out_signal_names.m | 109 +++---- CHANGELOG.md | 7 + Core/Algos/@BreachProblem/BreachProblem.m | 75 ++++- .../@BreachProblem/setup_global_nelder_mead.m | 22 +- .../setup_global_nelder_mead_legacy.m | 2 +- Core/Algos/@BreachProblem/setup_meta.m | 2 +- Core/Algos/@BreachProblem/setup_morris.m | 2 +- Core/Algos/@BreachProblem/setup_nelder_mead.m | 2 +- Core/Algos/@BreachProblem/solve_corners.m | 72 ++++- Core/Algos/ComputeMorrisSensi.m | 21 +- Core/Algos/FalsifWizard.m | 2 +- Core/Algos/ParamSynthWizard.m | 2 +- Core/Algos/ReqMiningWizard.m | 2 +- Core/Algos/display_morris_result.m | 2 +- Core/BreachDomain.m | 2 +- Core/BreachOpenSystem.m | 4 +- Core/BreachRequirement.m | 41 ++- Core/BreachSet.m | 57 +++- Core/BreachSimulinkSystem.m | 14 +- Core/BreachSimulinkWizard.m | 2 +- Core/BreachSystem.m | 21 +- Core/Diagnostics/BreachDiagnostics.m | 3 +- Core/OutputGen/alw_monitor.m | 11 +- Core/OutputGen/stl_monitor.m | 9 +- Core/SignalGen/BreachImportData.m | 8 +- Core/SignalGen/fixed_cp_signal_gen.m | 2 +- Core/SignalGen/from_file_signal_gen.m | 2 + Core/SignalGen/signal_gen.m | 16 +- Core/SignalGen/var_cp_signal_gen.m | 1 - Core/m_src/BreachOptionGui.m | 2 +- Core/m_src/DocRun.m | 2 +- Core/m_src/EEffects.m | 5 +- Core/m_src/GenDoc.m | 12 +- Core/m_src/ltr.mexmaci64 | Bin 0 -> 8688 bytes Core/m_src/ltr.mexw64 | Bin 7168 -> 7168 bytes Core/m_src/rtr.mexmaci64 | Bin 0 -> 8688 bytes Core/m_src/rtr.mexw64 | Bin 7168 -> 7168 bytes ...rgin2struct.m => varargin2struct_breach.m} | 6 +- .../brdemo_models/brdemo_autotrans.mdl | 29 +- Ext/Toolboxes/blitz/CompileBlitzLib.m | 2 +- Ext/Toolboxes/optimize/gbnm.m | 277 ++++++++++++++++++ InitBreach.m | 17 +- InstallBreach.m | 5 +- Online/bin/onlineMonitorWrapper.mexmaci64 | Bin 0 -> 327260 bytes Online/bin/onlineMonitorWrapper.mexw64 | Bin 197120 -> 200192 bytes Online/bin/stl_eval_mex.mexmaci64 | Bin 0 -> 307612 bytes Online/bin/stl_eval_mex.mexw64 | Bin 192512 -> 193536 bytes Params/m_src/N2Nn.m | 20 +- Params/pRefine.m | 3 +- Plots/BreachSamplesPlot.m | 3 + Plots/BreachSignalsPlot.m | 1 + Plots/m_src/plot_morris_traj.m | 2 +- VERSION | 2 +- 93 files changed, 1058 insertions(+), 271 deletions(-) create mode 100755 @STL_Formula/private/RobustAnd.mexmaci64 mode change 100644 => 100755 @STL_Formula/private/RobustAnd.mexw64 create mode 100755 @STL_Formula/private/RobustAndn.mexmaci64 mode change 100644 => 100755 @STL_Formula/private/RobustAndn.mexw64 create mode 100755 @STL_Formula/private/RobustAvEvLeft.mexmaci64 mode change 100644 => 100755 @STL_Formula/private/RobustAvEvLeft.mexw64 create mode 100755 @STL_Formula/private/RobustAvEvRight.mexmaci64 mode change 100644 => 100755 @STL_Formula/private/RobustAvEvRight.mexw64 create mode 100755 @STL_Formula/private/RobustEv.mexmaci64 mode change 100644 => 100755 @STL_Formula/private/RobustEv.mexw64 create mode 100755 @STL_Formula/private/RobustOr.mexmaci64 mode change 100644 => 100755 @STL_Formula/private/RobustOr.mexw64 create mode 100755 @STL_Formula/private/RobustUntil.mexmaci64 mode change 100644 => 100755 @STL_Formula/private/RobustUntil.mexw64 create mode 100755 @STL_Formula/private/lemire_engine.mexmaci64 mode change 100644 => 100755 @STL_Formula/private/lemire_engine.mexw64 create mode 100755 @STL_Formula/private/lemire_nd_engine.mexmaci64 mode change 100644 => 100755 @STL_Formula/private/lemire_nd_engine.mexw64 create mode 100755 @STL_Formula/private/lemire_nd_maxengine.mexmaci64 mode change 100644 => 100755 @STL_Formula/private/lemire_nd_maxengine.mexw64 create mode 100755 @STL_Formula/private/lemire_nd_minengine.mexmaci64 mode change 100644 => 100755 @STL_Formula/private/lemire_nd_minengine.mexw64 create mode 100755 @STL_Formula/private/lim_inf.mexmaci64 mode change 100644 => 100755 @STL_Formula/private/lim_inf.mexw64 create mode 100755 @STL_Formula/private/lim_inf_indx.mexmaci64 mode change 100644 => 100755 @STL_Formula/private/lim_inf_indx.mexw64 create mode 100755 @STL_Formula/private/lim_inf_inv.mexmaci64 mode change 100644 => 100755 @STL_Formula/private/lim_inf_inv.mexw64 create mode 100755 @STL_Formula/private/until_inf.mexmaci64 mode change 100644 => 100755 @STL_Formula/private/until_inf.mexw64 create mode 100755 Core/m_src/ltr.mexmaci64 mode change 100644 => 100755 Core/m_src/ltr.mexw64 create mode 100755 Core/m_src/rtr.mexmaci64 mode change 100644 => 100755 Core/m_src/rtr.mexw64 rename Core/m_src/{varargin2struct.m => varargin2struct_breach.m} (83%) create mode 100644 Ext/Toolboxes/optimize/gbnm.m create mode 100755 Online/bin/onlineMonitorWrapper.mexmaci64 mode change 100644 => 100755 Online/bin/onlineMonitorWrapper.mexw64 create mode 100755 Online/bin/stl_eval_mex.mexmaci64 mode change 100644 => 100755 Online/bin/stl_eval_mex.mexw64 diff --git a/@STL_Formula/STL_Break.m b/@STL_Formula/STL_Break.m index 650065f6..6a417b5b 100644 --- a/@STL_Formula/STL_Break.m +++ b/@STL_Formula/STL_Break.m @@ -1,4 +1,4 @@ -function out = STL_Break(phi, n) +function [out, num_op, num_nested_temp_op] = STL_Break(phi, n) % STL_BREAK breaks a formula into subformulas % % Synopsys: out = STL_Break(phi, [n]) @@ -33,12 +33,14 @@ % [ ev ((x1[t]<1.0) and (not (x2[t]<3.0))) ] out = []; +num_op=0; +num_nested_temp_op=0; if nargin==1 n = inf; end -if n <= 0; +if n <= 0 return; end @@ -47,12 +49,36 @@ case 'predicate' out = phi; - case {'not', 'always', 'eventually'} + case 'not' + [out1, num_op1, num_nested_temp_op1] = STL_Break(phi.phi, n-1); - out = [STL_Break(phi.phi, n-1) phi] ; + out = [out1 phi] ; + num_op = num_op1+1; + num_nested_temp_op= num_nested_temp_op1; + + case{'always', 'eventually', 'historically', 'once'} + [out1, num_op1, num_nested_temp_op1] = STL_Break(phi.phi, n-1); + + out = [out1 phi] ; + num_op = num_op1+1; + num_nested_temp_op= num_nested_temp_op1+1; + + case {'and', 'or', '=>'} + [out1, num_op1, num_nested_temp_op1] = STL_Break(phi.phi1, n-1); + [out2, num_op2, num_nested_temp_op2] = STL_Break(phi.phi2, n-1); + + out = [out1 out2 phi] ; + num_op = num_op1+num_op2+1; + num_nested_temp_op= max(num_nested_temp_op1, num_nested_temp_op2); + + case 'until' + + [out1, num_op1, num_nested_temp_op1] = STL_Break(phi.phi1, n-1); + [out2, num_op2, num_nested_temp_op2] = STL_Break(phi.phi2, n-1); - case {'and', 'or', '=>', 'until'} - out = [STL_Break(phi.phi1, n-1) STL_Break(phi.phi2, n-1) phi]; + out = [out1 out2 phi] ; + num_op = num_op1+num_op2+1; + num_nested_temp_op= max(num_nested_temp_op1, num_nested_temp_op2)+1; end % parameters diff --git a/@STL_Formula/STL_EvalThom.m b/@STL_Formula/STL_EvalThom.m index f22f25fc..adecc12e 100644 --- a/@STL_Formula/STL_EvalThom.m +++ b/@STL_Formula/STL_EvalThom.m @@ -52,7 +52,7 @@ end ii=1; -num_dim = size(P_.pts,1); +num_dim = size(P_.pts,1); eval_str = [P_.ParamList(1:num_dim);num2cell(1:num_dim)]; eval_str = sprintf('%s=P_.pts(%d,ii);',eval_str{:}); eval(eval_str); @@ -96,15 +96,15 @@ [val, time_values] = GetValues(Sys_, phi_, Pii, traj, interval); try - if(numel(t)==1) % we handle singular times - val__{ii} = val(1); - else + % if(numel(t)==1) % we handle singular times + % val__{ii} = val(1); + % else if isfield(BreachGlobOpt, 'disable_robust_linear_interpolation')&&BreachGlobOpt.disable_robust_linear_interpolation val__{ii} = interp1(time_values, val, t, 'previous'); else val__{ii} = interp1(time_values, val, t); end - end + % end catch % if val is empty val__{ii} = NaN(1,numel(t)); end @@ -220,7 +220,50 @@ valarray1 = [valarray1 valarray1(end)]; end [time_values, valarray] = RobustEv(time_values1, valarray1, I___); + + case 'once' + I___ = eval(phi.interval); + I___ = max([I___; 0 0]); + I___(1) = min(I___(1), I___(2)); + + next_interval = interval-[I___(1)+I___(2), I___(1)]; + next_interval(1) = max(0, next_interval(1)); + [valarray1, time_values1] = GetValues(Sys, phi.phi, P, traj, next_interval); + % Flipping time, taking into account constant interpolation with + % previous + Tend__ = time_values1(end)+1; + past_time_values1 = fliplr(Tend__-[time_values1 Tend__]); + past_valarray1 = fliplr([valarray1(1) valarray1]); + + [past_time_values, past_valarray] = RobustEv(past_time_values1, past_valarray1, I___); + + % Flipping back + time_values = fliplr(Tend__-[past_time_values Tend__]); + valarray = fliplr([past_valarray(1) past_valarray]); + + case 'historically' + I___ = eval(phi.interval); + I___ = max([I___; 0 0]); + I___(1) = min(I___(1), I___(2)); + + next_interval = interval-[I___(1)+I___(2), I___(1)]; + next_interval(1) = max(0, next_interval(1)); + [valarray1, time_values1] = GetValues(Sys, phi.phi, P, traj, next_interval); + + % Flipping time, taking into account constant interpolation with + % previous + Tend__ = time_values1(end)+1; + past_time_values1 = fliplr(Tend__-[time_values1 Tend__]); + past_valarray1 = fliplr([valarray1(1) valarray1]); + + [past_time_values, past_valarray] = RobustEv(past_time_values1, -past_valarray1, I___); + + % Flipping back + time_values = fliplr(Tend__-[past_time_values Tend__]); + valarray = -fliplr([past_valarray(1) past_valarray]); + + case 'until' I___ = eval(phi.interval); I___ = max([I___; 0 0]); @@ -256,14 +299,14 @@ time_ok = time_values(~ibof); if ~isempty(val_ok) warning('STL_Eval:Inf_or_Nan', 'Some values are NaN or inf for property %s (use warning(''off'', ''STL_Eval:Inf_or_Nan'') to disable warning)', disp(phi)); - if numel(val_ok)==1 - valarray(1,:) = val_ok; - else - valarray = interp1(time_ok, val_ok, time_values, 'nearest'); - end + if numel(val_ok)==1 + valarray(1,:) = val_ok; + else + valarray = interp1(time_ok, val_ok, time_values, 'nearest'); + end else warning('STL_Eval:Inf_or_Nan', 'All values are NaN or inf for property %s', disp(phi)); - end + end end @@ -306,7 +349,7 @@ % Last time instant if(interval(end)==inf) - time_values = [time_values traj.time(1,ind_ti:end)]; + time_values = [time_values traj.time(1,ind_ti:end)]; else ind_tf = find(traj.time >= interval(end),1); if isempty(ind_tf) diff --git a/@STL_Formula/STL_EvalThom_Gen.m b/@STL_Formula/STL_EvalThom_Gen.m index 44e8d4a5..68ec8384 100644 --- a/@STL_Formula/STL_EvalThom_Gen.m +++ b/@STL_Formula/STL_EvalThom_Gen.m @@ -100,15 +100,15 @@ [val, time_values] = GetValues(Sys, phi, Pii, traj, partition, relabs, interval); try - if(numel(t)==1) % we handle singular times - val__{ii} = val(1); - else + % if(numel(t)==1) % we handle singular times + % val__{ii} = val(1); + % else if isfield(BreachGlobOpt, 'disable_robust_linear_interpolation')&&BreachGlobOpt.disable_robust_linear_interpolation val__{ii} = interp1(time_values, val, t, 'previous'); else val__{ii} = interp1(time_values, val, t); end - end +% end catch % if val is empty val__{ii} = NaN(1,numel(t)); end @@ -251,6 +251,49 @@ end [time_values, valarray] = RobustEv(time_values1, valarray1, I___); + case 'once' + I___ = eval(phi.interval); + I___ = max([I___; 0 0]); + I___(1) = min(I___(1), I___(2)); + + next_interval = interval-[I___(1)+I___(2), I___(1)]; + next_interval(1) = max(0, next_interval(1)); + + [valarray1, time_values1] = GetValues(Sys, phi.phi, P, traj, partition, relabs, next_interval); + + % Flipping time, taking into account constant interpolation with + % previous + Tend__ = time_values1(end)+1; + past_time_values1 = fliplr(Tend__-[time_values1 Tend__]); + past_valarray1 = fliplr([valarray1(1) valarray1]); + + [past_time_values, past_valarray] = RobustEv(past_time_values1, past_valarray1, I___); + + % Flipping back + time_values = fliplr(Tend__-[past_time_values Tend__]); + valarray = fliplr([past_valarray(1) past_valarray]); + + case 'historically' + I___ = eval(phi.interval); + I___ = max([I___; 0 0]); + I___(1) = min(I___(1), I___(2)); + + next_interval = interval-[I___(1)+I___(2), I___(1)]; + next_interval(1) = max(0, next_interval(1)); + + [valarray1, time_values1] = GetValues(Sys, phi.phi, P, traj, partition, relabs, next_interval); + + % Flipping time, taking into account constant interpolation with + % previous + Tend__ = time_values1(end)+1; + past_time_values1 = fliplr(Tend__-[time_values1 Tend__]); + past_valarray1 = fliplr([valarray1(1) valarray1]); + + [past_time_values, past_valarray] = RobustEv(past_time_values1, -past_valarray1, I___); + % Flipping back + time_values = fliplr(Tend__-[past_time_values Tend__]); + valarray = -fliplr([past_valarray(1) past_valarray]); + case 'until' I___ = eval(phi.interval); I___ = max([I___; 0 0]); @@ -310,7 +353,11 @@ % first time instant ind_ti = find(traj.time>=interval(1),1); if isempty(ind_ti) - time_values = [traj.time(1,end) traj.time(1,end)+1]; + if ~isempty(traj.time) + time_values = [traj.time(1,end) traj.time(1,end)+1]; + else + time_values = []; + end return end diff --git a/@STL_Formula/STL_EvalThom_Gen_Rob.m b/@STL_Formula/STL_EvalThom_Gen_Rob.m index 6a0b5704..8c1fc1d1 100644 --- a/@STL_Formula/STL_EvalThom_Gen_Rob.m +++ b/@STL_Formula/STL_EvalThom_Gen_Rob.m @@ -106,15 +106,15 @@ [val, time_values, robustness_map] = GetValues(Sys, phi, Pii, traj, partition, relabs, interval, robustness_map); try - if(numel(t)==1) % we handle singular times - val__{ii} = val(1); - else +% if(numel(t)==1) % we handle singular times +% val__{ii} = val(1); +% else if isfield(BreachGlobOpt, 'disable_robust_linear_interpolation')&&BreachGlobOpt.disable_robust_linear_interpolation val__{ii} = interp1(time_values, val, t, 'previous'); else val__{ii} = interp1(time_values, val, t); end - end +% end catch % if val is empty val__{ii} = NaN(1,numel(t)); end @@ -274,6 +274,50 @@ end [time_values, valarray] = RobustEv(time_values1, valarray1, I___); + case 'once' + I___ = eval(phi.interval); + I___ = max([I___; 0 0]); + I___(1) = min(I___(1), I___(2)); + + next_interval = interval-[I___(1)+I___(2), I___(1)]; + next_interval(1) = max(0, next_interval(1)); + [valarray1, time_values1] = GetValues(Sys, phi.phi, P, traj, partition, relabs, next_interval, robustness_map); + + % Flipping time, taking into account constant interpolation with + % previous + Tend__ = time_values1(end)+1; + past_time_values1 = fliplr(Tend__-[time_values1 Tend__]); + past_valarray1 = fliplr([valarray1(1) valarray1]); + + [past_time_values, past_valarray] = RobustEv(past_time_values1, past_valarray1, I___); + + % Flipping back + time_values = fliplr(Tend__-[past_time_values Tend__]); + valarray = fliplr([past_valarray(1) past_valarray]); + + + + case 'historically' + I___ = eval(phi.interval); + I___ = max([I___; 0 0]); + I___(1) = min(I___(1), I___(2)); + + next_interval = interval-[I___(1)+I___(2), I___(1)]; + next_interval(1) = max(0, next_interval(1)); + [valarray1, time_values1] = GetValues(Sys, phi.phi, P, traj, partition, relabs, next_interval, robustness_map); + + % Flipping time, taking into account constant interpolation with + % previous + Tend__ = time_values1(end)+1; + past_time_values1 = fliplr(Tend__-[time_values1 Tend__]); + past_valarray1 = fliplr([valarray1(1) valarray1]); + + [past_time_values, past_valarray] = RobustEv(past_time_values1, -past_valarray1, I___); + + % Flipping back + time_values = fliplr(Tend__-[past_time_values Tend__]); + valarray = -fliplr([past_valarray(1) past_valarray]); + case 'until' I___ = eval(phi.interval); I___ = max([I___; 0 0]); @@ -341,7 +385,11 @@ % first time instant ind_ti = find(traj.time>=interval(1),1); if isempty(ind_ti) - time_values = [traj.time(1,end) traj.time(1,end)+1]; + if ~isempty(traj.time) + time_values = [traj.time(1,end) traj.time(1,end)+1]; + else + time_values = []; + end return end diff --git a/@STL_Formula/STL_ExtractSignals.m b/@STL_Formula/STL_ExtractSignals.m index 98584608..bc406f86 100644 --- a/@STL_Formula/STL_ExtractSignals.m +++ b/@STL_Formula/STL_ExtractSignals.m @@ -18,7 +18,7 @@ for im=1:numel(matches) signals{end+1} = tokens{im}{1}; end -sreserved = {'alw_', 'ev_','until_'}; +sreserved = {'alw_', 'ev_','until_', 'once_', 'hist_'}; signals = setdiff(signals, sreserved); @@ -35,7 +35,7 @@ end end - reserved = [ sreserved signals {'alw', 'ev', 'and', 'or', '=>', 'not', 'until', 't', ... + reserved = [ sreserved signals {'alw', 'ev','once', 'hist','and', 'or', '=>', 'not', 'until', 't', ... 'abs', 'sin', 'cos', 'exp','tan', 'norm','sqrt'}]; params = setdiff(params, reserved); params = unique(params); diff --git a/@STL_Formula/STL_Formula.m b/@STL_Formula/STL_Formula.m index deb96fba..82e704b4 100644 --- a/@STL_Formula/STL_Formula.m +++ b/@STL_Formula/STL_Formula.m @@ -261,7 +261,45 @@ phi = STL_Parse(phi,'ev',interval,phi1); return end + + + %% test once + [success, st1, st2] = parenthesisly_balanced_split(st, '\'); + if success && isempty(st1) + phi1 = STL_Formula([phi.id '1__'],st2); + STLDB_Remove([phi.id '1__']); + phi = STL_Parse(phi, 'once', phi1); + return + end + + %% test once_[ti,tf] + [success, st1, st2, interval] = parenthesisly_balanced_split(st, '\'); + if success && isempty(st1) + phi1 = STL_Formula([phi.id '1__'],st2); + STLDB_Remove([phi.id '1__']); + phi = STL_Parse(phi,'once',interval,phi1); + return + end + + %% test hist + [success, st1, st2] = parenthesisly_balanced_split(st, '\'); + if success && isempty(st1) + phi1 = STL_Formula([phi.id '1__'],st2); + STLDB_Remove([phi.id '1__']); + phi = STL_Parse(phi, 'hist', phi1); + return + end + %% test hist_[ti,tf] + [success, st1, st2, interval] = parenthesisly_balanced_split(st, '\'); + if success && isempty(st1) + phi1 = STL_Formula([phi.id '1__'],st2); + STLDB_Remove([phi.id '1__']); + phi = STL_Parse(phi,'hist',interval,phi1); + return + end + + %% test av_eventually_[ti,tf] [success, st1, st2, interval] = parenthesisly_balanced_split(st, '\'); if success && isempty(st1) @@ -270,7 +308,6 @@ phi = STL_Parse(phi,'av_ev',interval,phi1); return end - %% test always [success,st1, st2] = parenthesisly_balanced_split(st, '\'); @@ -420,6 +457,15 @@ phi.phi = varargin{2}; phi.interval = '[0 inf]'; + case 'once' + phi.type = 'once' ; + phi.phi = varargin{2}; + phi.interval = '[0 inf]'; + case 'host' + phi.type = 'historically' ; + phi.phi = varargin{2}; + phi.interval = '[0 inf]'; + case 'andn' phi.type = 'andn'; phi.phin = varargin{2}; % array of STL_Formula @@ -462,6 +508,16 @@ phi.interval = varargin{2}; phi.phi = varargin{3}; + case 'once' + phi.type = 'once' ; + phi.interval = varargin{2}; + phi.phi = varargin{3}; + + case {'hist', 'historically'} + phi.type = 'historically' ; + phi.interval = varargin{2}; + phi.phi = varargin{3}; + case 'av_ev' phi.type = 'av_eventually' ; phi.interval = varargin{2}; diff --git a/@STL_Formula/disp.m b/@STL_Formula/disp.m index 0cc06021..c486b6ce 100644 --- a/@STL_Formula/disp.m +++ b/@STL_Formula/disp.m @@ -1,14 +1,14 @@ function st = disp(phi, opt) %DISP displays a formula -% +% % Synopsis: st = disp(phi[, opt]) -% +% % Inputs: % - phi : the formula to display % - opt : (Optional, default=1) when printing predicate, if -1, the % function doesn't display the id, if 0, display predicates in % full, otherwise, display id and not predicates -% +% % Outputs: % - st : the string % @@ -26,14 +26,14 @@ end function st = form_string(phi, opt) -%FORM_STRING +%FORM_STRING % % Synopsis: st = form_string(phi, opt) % switch(phi.type) - case 'predicate' - if(opt == 0 || ~isempty(regexp(phi.id,'.+__$', 'once'))) + case 'predicate' + if(opt == 0 || ~isempty(regexp(phi.id,'.+__$', 'once'))) st = phi.st; else st = phi.id; @@ -82,6 +82,38 @@ st = ['alw_' intst ' (' st ')']; end + case 'once' + st = form_string(phi.phi,opt); + + intst = phi.interval; + try + I = eval(phi.interval); + catch + I = [0 0]; + end + + if(I==[0 inf]) + st = ['once (' st ')']; + else + st = ['once_' intst ' (' st ')']; + end + + case 'historically' + st = form_string(phi.phi,opt); + + intst = phi.interval; + try + I = eval(phi.interval); + catch + I = [0 0]; + end + + if(I==[0 inf]) + st = ['hist (' st ')']; + else + st = ['hist_' intst ' (' st ')']; + end + case 'eventually' st = form_string(phi.phi,opt); intst = phi.interval; diff --git a/@STL_Formula/private/RobustAnd.mexmaci64 b/@STL_Formula/private/RobustAnd.mexmaci64 new file mode 100755 index 0000000000000000000000000000000000000000..7c1a7c601a344e933ddab8567051e902686943d0 GIT binary patch literal 71460 zcmeEv3t&{mx&PU00?R|r20^eD-CES7SWFa^2x=l(I7fDQKY|iNfCO>{5|dpXDiWIn z*>2aSSG}e6+NKYCx%QPlw5U}#1W7=O0WIPSqEb2OT8U6e5GDWLZ|3YX0R`Xx>w(Rj zIcH|h%s1bB^Sx%~+4uf+ytkrQtcs%8@Ut`Qr6@Iu1$T;aHhwFU6s4eGhBI%5cohGq zH9o4C@f1Af4`qw1pukhK(ql#tB$nssBj26zHyJXX98JzhWo)#dpu*#wUlDnfSl-Cp z^3|Ws6pYIj$p<#GJTz5Yvb=)DMN7(x%JC$zy!~c*X=Wje11!<2Tm2R-SWr;3azRm< zr@&JUjlT-*|m!#}<$C|I_npkme1`K3z=$~@&KERVP^u2z}f zj48yAbHfpY1qF*rqfqN!KU=FzoGk-|an>h%vApxb5rhQ=OA1d`Kdn_JZa4EV9$OyA z*G1+#285f2UqOLOpES{#tIyz5T;T#TWHcNfZe}Lhn5ZKXoUbUAA}R6_Ha3KveDjVh zUqiT&6?qr^gn)fH6u&)){}SQF7K_q3SW)`nehPlPR+&Ghy$!!~{7!TYMQxlty!<+z z@jK^UcG!F2{%iZzb-sC5#zODUhU1x?>HG9m6t%DNt#F*raP`M84?pIWcsB%h7Uh!Z zt13K2OD}Pi%r7r2UvD@x06uDE1e>4MV2k;UN$m&__EuPDKwxgnjNSUxmO-&G(O-**UXv zX6DS8K1K6Aqx+6%{w(9i;8QgJZFa3Ds8$z&avJNzlQH7Kd_Gu#2fD8bscgp0yw7U# zevNsI{K%W3##H&n(_af*U9}6@M&iL!*?_n4`gVN7=WNmZV~h-uWwR)3xVV3skI%%d z=3m|7^1bQu{nOWAEGZ4={v~qjKIX6+hr~T{+&0vBQ{1y!cH?>6yL<;+zPDYz_mF!e za=ZLXQQSe4Xk3CBU$h`QO>1a%Xpa*MI7?`jMy=tP<0*0P+nc$|xI>iME9S`(@npPB z_g~@ib!om$M(y4F+CgI-N?`c@Gve#UN)bO`yd~mY#$plg(yBJwZp@jRlb>@_PCSZ;XIzRG$zGl7Sbr)Wz@AcfGHT<);R}i`qzSpiQiq{D3Wr2DVK8M5&$E{k`acg;Iv3g#$d;}!;^EPyo|0bK;e}`SGYP9LT zn{2YWW`?8{dyviIIRk%_y!MT(d?;n(Oa!`byu+1s%ri7?%1#p%Ysz+*A?G#)&pAIaB!7aCf0Z27J|RO* z&CbyMYf$eM4*jp;e$;&JddGgzNVFIBRn+UAuWBI7C2{`*6@Z^ zx1JqJ%6vI@_B1O?C2H7vstt--G$uWJcrEk#!$;-{Y#&`C3 zQ`@%SE47(HMAYiX_(lI1)jkoG^y25VYw7J6BwE9JR;^^0s8QE85ED(!ZBb`8>sGfz z%i8A6)O;N62i?9MYPvgU{N@JWahf|w@cWBnhY1-q_erVP@-jEfVU~>gVwXjWE)&#p}h&i$_tXzSy zy54ZW>b71JvN|*IP47CFZ*?ug^$6=U|0I+?u}fymUw{*jcR3+*GX2YCM#qrsfXMK*Fh`@h5LI5^Y23ZA|?dQonIX&3_50pF!&F zOzj#zTK5mw$j%6zSv)d4^acIUtC|eZZawQ+Z*Sc{t5dUVLZQ=)Vs+%s^0WB(RgB(F zy=qIREAXf&VtW{bvc$o$C34&w1PBlUL*gYZ>lv0iGrrtmeEfGk;O^9X?v1)XAFn}a zk<0hD&=Xp~yG{$t+yJ_33p-sn zRK}y1V~l_b=>Ew=b^mB0P}WhlG8<`IQB1bM@rW^muV5(PD|;hf0bH*$kjB~K{r0UR znDIN-9Tx$XGv?#>eo*0Gf5^mA5 zfOkOPxzo_DInz*+ylL$TCHlwXajJ78{>%)5C22+r#S7p{o^xS zJ~DcDfQGNc6gdg}4j6(6<1Sc(*U4z;{^d3>WV?%Xby=`jQmlR=D%{DicVz%!7`EmuL@$O$Q?d3$M>q{Pt~$oJm+YEmH1#@r{>!dN{gMH zg}iV}rxtjUQ-v1zi6MeVWU2Nc_|ynYP%R+nFM^=oM1p=33HnX#>e^pJ?S+@$E=OI| z@B9)C`I80lSJbt6c$0JFX^W=-^gXZ#3?9Mj=7sqJpEL6BPkCEf2Dj+qe+Wb1re&_K?mw_v6`jw()K6(_NZliJDt zXk#pD&EEjSw&(B%`~hoNaaBS_QSst-wdyBGgc8+iG2;g`fNe^9+e@f!c>ZC#y!{B) zn=sY3hf3JQcC(3{vWW^N*qA0ViY77RQbl297JRD}1jMdtcKZJP*hS)T0ZT2XAElH~$Sn*q6` zL+VZ01ROsiSagIB+FAFenxXM6ViYYRACDF>joG3*pp}gOJUW2=lY{;NBf&23R&l+1 zCde%^-&Ev#53QQtp82xGfiV_OKip|XTj~d0UA0gO&e~|TowbmtDmDMib#0I0sW}j$0}H^~4q)}c01#aQ$fdg1v!FT@v>~RT z4Jc?m3aT@k{rv(I7dP6XL@C;0pr)H76e8T*@$7gqzj@=q6Zg<;cRic25%WY)wicn^ zU5}5FKL%kmzQ&Kz^e!mDbz2l&l3FW zJ}v7oCA`%TR9`^HHaop1{BrvaBnxdSkJgUQ`Qt7H=$4 z=6+GjYGfVV6e96>D(m>Xy7nI&1HQfHTQA;*rgnlL<+$8D8MGFv>MM3pf(dwrL>}2?}fJxXO1(qz;$Rcy4HU^D=nIA z!i%j&ZjY)3CK_#LVa!W@2hUAl3-Yf8))VG!?{c#B2@v!VS_){cFzQSocpbN%%c}Hw zoQa{s!PEpbML>)(z$P@gTVCQ6#_v>)->DqGQ!#$yO7M@vW6%uznYjV2s0WW%XO?MP z0H9<18pHA#wu5MBF@rbClXc_&)*~ZIbl2%Vd>^yF7|$P|DZLnloNXU($6XD{pd97L z{>%<;RA&bPV(}b_K$=fc3*~E4tN3*&?vWqNSmC?jFZ>8!I32y#L}=J1rs+?{Xzuim zH>KvTLX3YctHSQ`{gxD7t^OS`)zn?aanx=9CF%u+&+cq?`Cd1!7#_A#9RJg&Sv9qK z3dTpzb)t8HVD!=XAlN<2k6SFeT<(!3g;FaXRwnG0kR&=9j&T(ceR# zs?~R&s53*WGPjDF0AvZE^HS%BcR;@Vhd7}38Q;57!p;6i(y7SA6#1y`_Y5~@63=kE zTJ1mKXP2L-vtX(+J8R!J&+`<8NMp4R4C-@CMAurtO^6FgeY54$9nD zOl2;#y!M%(0I7l>L>SQ6Jxw)a(C{%Zcn_0P1P)fxKGyy%P{sgjv5Q}Y07`(*6u24- zORD6;ofr>KWOFxDtA1iJH?DCYfgAXB&Hn_4w6W}MvWy3fEl`;DmDKOIxxmZniwipj$@WHYuN5gx+XSbcY{67n`-W?9@(I|Q9)H+@h z@_t~{E_c=}yXU&F3BdQBmc9u#pJ_UTe3x~AZoMN-^F`D5-xW@o-sB1-uhC(qb6b;l zg@$%d>CD{fgdNAX&*j^Odt>xvM6>bGL`)j3`6l8wPH-;c$>OlX^EQ!#nKT-A#DT#F z9+r4|?Trvr)10vHr2Nu+}eB47Y*Aa#USGg)73x5XUq{ zTkSna4Ir|2hKke&jQ=)M=gnejDlP2nC0bJ($yTC(f1&COZ;=HVUq=YDXvD^FqWMjr zEcn!7F>9qeF?FRo>-h&GAl+HZKb80sGtCWRZBA`YJDj7If?b3(K{|F=U6Y;R_Rj!w z3!;(cvg~$4uV9Pq|914hn;Hiqfg83UH>{RXGZ2h&=fEfzH3Jo^Wx+{M3f<9kSiK`< z3Z}_ob+@3XnO!+jp&pt1LL=1kvSA%ZFWMn{qy_|01s@`6A-*aq2ldh&O)g)HhMCg$ zj^^8~HN4%M^%x}{3j8#2&E?w#tOPBB&9N1>sbs;U3~5Wp=rH+L+6x=i>LGYS^yVMe@C*PRl26`!oCLrC!hCftIvc!svn#N)POI7K zSrdgxEi+BP^p%5Y9dzHaN%Mnb`(Dr*4x)p`9#$LSDPK2YNH9KO0CLS4;>99wgwoWz2Czm=*P_C z=ghO4rfpvbZ~(D47$=w-hjNa%;W|%za?a?&D^T{fy=XPnr|w87PcFPXw0k_8sT9FK^Gw^qO^l9&1kl@?L#y=Kr(~6UzPYY1^8qWoz#Va2}w-g(@}lI0PW7B z@dzclaU^Hw+iW)-T%g2A(*hGL zy3d&g+@h{*y=K8YgNhn9t!i~M=BNh+`SCBU^sI4b{X?yO1TZqkoo?;F*_Cxvt^O^Z z$$_NK71Q|%+K!pAzdbUPgzCM)+e`J+f&enptga>d#{_~phOUZs2K4v%yk}Ybr#(e+ zpN-`F6UJv~dTj1oGT^Li&GeJ?O|l&v0%zlTOXka=RFTDde`XMoO-TB@Okn{54)EXImALIxU+>BP0ZSRcfDfT7&YFz29 zo_z8Rm~iz#|LvG?!9V~5t*M&TyIu_KgEl-p0!p5&TSvVg8WaT?{ImQZqg4$yEo(O@ zZq+8#@C9u|mUd^Cz;AFBjRol2n5yYjn*k?@Q=*1u z)}$3XQGjqO>!e#5T?64(R>{I4ExEJa@?0&-I}_!x5Fms1?eN@79WS_|uSdU5{wm^M zh7u|vhLCxoe_4vL;}?Wo{sxzSbv>p9Eq#y6|1f(K@ba(52$xJsp#L*~4(3A>W~<4w zV7|ii2!LtUQO9C^Xg(Uen&aR#Dq3U0dyFwEre;t~f$X4`qJ|Mbf%!fmpn{41cl&>i zmeP-p{&(i6tWWg61AOYyZZHT0&L5D4da7=+Sg3Ev7U~sB4kd+zD%t;lBn_)8Weq*k z$Q7OtcEBEG=Qy&eqI7f)+QcSyG{bDTEa>c_tekgfFv1J6Q|(kXnHAj z!=iP}7KcRw0;hsL9}NQWI0Ira#^@jO?bF4Ri&;=(U0mDAn}Nl{U>Xqh&y2^9A0P+y znPU+4EZ?0(KEHvV`x49N>!HItCHZ{zuh`&y#!n{#T2ekwHXr?Fl6Xb=JoSZ$eEzH9 z1aFt|t)I$_|AjaU_!{D-eE!C65HcyBuN0{d81Mf?rrJ23VUO~;+bn1&lCuA9L)dfw z(LY_g^DUBgh+U^4pL~ogS-@Zgb zAv2hqNY z(NF|WsG;bt-Z^dgd`Zl=PZv*weEv-q6m9!Qkk8+#mGa&F2u~v4RlSu)bCKpdtouHI z?R6{6tU)Lx8sWhp2!<@z5g%JRz?gLygy5el@wy_WSnz{~@Y9P2Y_aQ>gc;;AtL zwGRz23qRCkzV9;b67Rc=er79Ihb}3j%StRF^j~k+{MQY2`7Q9Vb!7$BdpAW^M#0S%mR>A~zR7^jdD$D(LSM;0vu$Ya zo4lKBhizyNAhs7KRk+aSy`-+~N~Z7rksRTc21|Qvb+Ym8S75t2vdQ9sU*IZOWS>O| zFv!m3pE;$SD5DhC!jU0$?M@+@&xLo^9QgO;y^b21`REP5Bl|CO$A?$@+Wz>W`G$Vc z&^psbJ2xBlRC^vuw9jMNSSFa)idS23Pgm7e{7~ha@I3WFP1wMq-{P|=;#q1Sk497J zB_wYB0j7q9g$W>ow$M#z;V7ao9n;-#-**nBV}A9|0cEt=acRUVwC(wrpva&*)i2h@8&I71n_%&f*n}>LHMI7N&M)@*VVNv z@QA5AQ#Iei8)UN{sFz`2BU>SxCvN=#ra<$UAl$qf_&vxTjcuern@#vCojmEvzD*#7 zus6=OqcPXB3vOT+a1r2~Mm%~6N#&2YFlQ4U9I^uP+4?NQn+*a^2Yb@N)!oPd!SN= zfpyVOh+BVvDbNfi2zN$jru;-0*U$|Za4f&ZDv~9vtcbR!malz*^&+ULV<2HBZv6rA z-hUt8w>^M5qlSBM&l+6u68-@$lSe(TL6uNIF$echQm;r}k$%I@+f| z*~{@A2dPu<8g{I!3+tiKge}#(JW(HcAT{YtF_F5MNL}2HBp973t~2ize&D6d0V@A`laS1kbFI)GFKI+#Um? zD76ePC7udrAI?W}1$DfRcyXN|cF`U-$=$1FC9St6c;?BfFafHPhajZ#6*q1O z+xEls@7w6LJ2!6x^kUr)#T;SBL(%eyX!&CKwFk;%7+A@|Wy{5F+~Sn*I4or8AJX2B zF+aost*05H8_>jR8PgM0R309w=1Lg|UM=9DICDRAv8XoIo=4&3+t;=o6iC2hoXc0V z9^IN>hd*!|ktNZDB$mp=4U3yl)+gHU-g3BV`mUQZqN3T9^E4ll2HNN;+t%GS1y*tU`g{sk!3z`ugB(9KMuVe z_TLV}`^&uF;pSEBf{(Y~;YH!~;c%z(puC8>p8FkgBSr4kIWRN~HVE8#28ZDXICr|R z8Q=-`KSWvP{)h4SE&Q{p-qNtQB=(q`V9(qNe0QhsQ15M^`*y;8~4Df{^DX15cVY zj0?G|ppMNWUFnDPtQVjuU$3rxiTM5~1Yut1VNfNxEgfi@OC5)$@Dql@PgwdeVh2)p z4c0t74uJp*-0QHZoO)Lw7yVUA) zkyyuSa^ErCw_B%f-dWGh1YN$#@NM_j8^2-#>`+G_3n-GNOSZNSgfHifU9W66v6?;z1;Qyl4k~8Be+z^ zS$}xWBI`bMXmk?(ZKIq@A5AOu6u)k_J+^}{50@qBYr^_KFOVQfmbzGB6V9X z{s{kX>`S0$?N)2ZWkMHGkG?~WJz9F_@_a%00~%(4wrjB_!e-HSqVf$|$BSb9oNup= z#YyQeaSOqQE-O&aGg#IT`}P`}y{z+#EN^mP6x5quEcQ-*2DREKw&nzpml>0gkt!v{ zg?WHI{w)lcI&GsEC>ScB2kKonAVC!WSu}jHF~I~U0ib%r!KCX0qd+JQtJNtS48C_F z_&Y}PWeE>`VIbV={g-Uz%#ElSx+DxEw}6qB^_*uQniO4sQ?<$FMMb%S%QMh;)PrgQ z!jbo|)c}ur@flZ2iB_6DfsusxVoVd;)tY;uY=I~JddwYm_Hu;2`LVhT`!-+-YJ|l= zbgzc)4ZW%RuZ1xXJ-E6advk!QI5*Nb$Tgai?RYW)wzD-rsuJf0qN{G1;Na2@EG^pO zIV(~>3|j0T+vr8XXsz&Ff42hAi{D_un28Y>y49G(0G{jgKK4UxM7K4#IS+~AW2~ol zP(V_Y`7@RYi{eCtYCkA34Dp1xG$ucYMF-*b(w*8PDgeKIyz;(n_{=MPgx8AO~m*ZX}Rv zNkrRM_4KFp^jF-zH%X)2HTym1N*gM+N^oO4QXp?{R?+vO+t|8+I2am^0)c}$Pf84SzT>Vr;u((d)r33u9;(4v ze~^~GFE&5;6yoo8cg?>%1JO*EuhBSs3yI$zH{huIahE(?ubN;7s}s8cG?pxzg|85W zW0y6Q;r(l9yKxZ+ojJb3{EghN`!nmGMQFjN(?744eg6G39d-CP{c{&^@g)7D`Bm<` zjZI}eK%H0Gc!r7FUkY5{n0mTm5;2>rl}ys_3V3W5edlp846yAv=%Z(-p8mYx(DxFd z_LQ0xF12Hr*d_*Y-$er^*xR^vP)lz<(KtCjGDaGa5MwVgOlF}(j6RMMJuu0N83m^9Vu)ku%wit%xo=DQRNugIul1<$MAf9d}7uxm8N#~O|g)(2w)x8TpRIygR# z$BmCI7$2D9LH5blG#a~?g@KPE(2CsQSP(tIhAnUsM+b{0RS-qjyzG54w8Q9+dPR#j z_hXnf{V6-18+V~-l2#BnnENq>U4Dk(YzXp_lCO5n+)p=gFa;wG%|I%b97q>ngDEWF2d z=~;&>z9EUOa~&C2Ms6R4+4$^e z^% zvneuhe}p|IGDQR`4)AGU?$o=Q!J6X;fme}GG1~tF5FTr^A&9L&6L22&h4?VZCYM)M z9ks!1F4}9waKVsiD-k@t$VOxnxReZpb2f|S8TX1piDY#^GB&Qx*wNY5<@PTFVL{

x|{5zLwn*2Ky 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 literal 0 HcmV?d00001 diff --git a/@STL_Formula/private/RobustAnd.mexw64 b/@STL_Formula/private/RobustAnd.mexw64 old mode 100644 new mode 100755 index 767fe917f6cf513c86199409bd8bb0f71988eed4..3f44ba3eee15958764656ae6a428a30b95309139 GIT binary patch delta 3768 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 F{{ctV8D;MKT^AYn7wJeFi7 zfR|0xGm~k?rgf6Z==jK}6ci^WtI|Lwh)%TC*u+px;!V(or0GZ+b^HD2E*7VE=0D&6 z_|AWx|JiNrl3Kf@?XBM7i25(Lt)0^|Au}@H?onay`0)=tK7spsUIF@Mz17nJywP!| z=XbzuYs-4x5%Jf1S_K{q_1iD7ZvCn!C?^YjwbhKRemR^CE*ff>@Qtywczcw=%vdH| zNxFNG$4U8NwmpnLAQegvbC2Yc()bTjh7{YKYA7-!{v(+&r7h_BLQx-*m9`IBOxiGC zXDpX?@;8k&-USp^ms*szfG1hYgjLgNbigxRn<)&JL;k8)VoZw{i2|M!MV+DrXWk>q z+IPYrq8~)`m9;P6Qq)UCy-aHPX-|?!Iy4bjYS98SnU_K>(TYE&wg6-FAlg@jm1!pg zPg6Qwj!ew0rIb=_7tV1p!e*h15jG0-oJ&3HR!=MH8SS=}M%P9S#W(vzwx_^wtN+VZ zh7=ZUp%`DKeABh8iF^pyCMT>x!UH1VI1&aG^&$4RMI)8FXh2a8E@mp{5k%%hZBxg%U_&?<= z-Y;hvS59S&e=Gl9{uii0t1XA`h^#h*-{qGgi=?l4lsPBq-E8y@JMGT-q9v~8^b299b_tGmk&*jsa|60u>%L8n8sSNMw5O;zv2ljnWW)(ihf(1(Vq9#MQZ?0pRBgVq7KFa|0wXnlzE zPSa4DfD>F!Temb9Mq42Em2_ecy3}tvO-XRAQBpQ zl-R>I3z(j3qu~or&{9;>I6sk=WdC<6(Vha$t&X5lW4FF462)8)fuHkRX|{?0!pgjA z)`C}P3Fw(*(Y8MHnbLwn+K%vF5jK~I#Tei*doO~K+`=#w#~ zHiD72gMCV{7u;j3F?)q4JLIVnJrj9hMoQB6(UjBV0YOpSj;f&bs_ywEe=?(7_F|6} zf5m2gFrz?Tp&PX@(z%?uQ)=eBGUs`?a)d{p zp&~B`THnL(q@w0Gkp2#ImwKtD`0qjMu}S)$i39rFiQst590ZXJ*@^)qGxdrNNZcy(PO{;)f*5 zk=Y%R>0B;rm3E{i@ZGshk(LA)Sa&aLP*fo43r8xDixE*-QY0yJJ`aTWWS3|ayFDp!6+%$u+Bar^k97s1~n+}jYGn~yFOl0xLtSqu) zy5QZ5MH*S;-l@#Ec?Q#S@OKOIDg)_^U4|6=R9_P5CI@55WYdyLril1`zLr>~_v6_` zb5dy?kA>D@nZwvQr@jv7PxN(E@)wKJmk_HX#Il1Gz@tyAy$hu8L6j`nH9-1Kglx%d zWabhxGdG7f(Vn;BS0bK&Ta@4xS~g>r2k}@CYjq4W@6=gUId~5tyAeyJN1`Qx-R}!$ z?0a0le%zb?i|Kv;hW@S8Up6p#dA!JX&o@KnzT!BO$jM(TejxQiiT)TJ#XJ6bA!D<# zM#96e-vl=BJH;thV$qGuDMCd+o&n3n3ri9TCnD|e?tvUdgub|N0}C%Q6imc#A@-|c z#;$QsN&3Bf?Z|r^!peaBV97MYSUi8fWU*As<4QB6Q{D4QZ%I-qFD#o@R)868Gi}`b z;F^}&X7(sFm#3+5{i?@X)+}spetZjK&*{;nj5V(R&Bo1ns~a0xUAMQaIxKhM5Ak;h z(n2OggM9-s1_|IP3VRqq{^R^vytw=fA2T?PEJ!wZKaWSjqgYUQY%yf3!dNY^8Bzs* zD^P>%hF*}!*jfnbO~5|LUg(pHaB=}sA>M&p0Ef^s6{icG@D<1*7yj*1joGI$mWXO0 z9D~$DCk)_kA?bwKsH!KRPp-Dfl_sic7HSrp1Hd6jD|EtMlu#4pnN(VOS$XxkqFU;L z$fz;GqmXfQApF3I9e_?n^fXGt1rC+U6_i5<^bz3mD1lF)PcDFX6v9==IQ)b+AsY0_ zm)`Bgjh?u{gfHMvV2gO14Mg}2O80m!9LOS8ykWRIf1~Dq# OI~L5By5&XVVgCgK6%)n) diff --git a/@STL_Formula/private/RobustAndn.mexmaci64 b/@STL_Formula/private/RobustAndn.mexmaci64 new file mode 100755 index 0000000000000000000000000000000000000000..15385a655a22a7d4d285dcd6207594a699146dc8 GIT binary patch literal 71524 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 |>9Q57amoMDXU}=x9P9DDf0&F+?HrRad3%mgq z*(Xr~46?KMXXcV_l(7WX!VwX5^>!he&w_W>O!)T|y^I=~@6j9niM+qj9UorptGNe^ znL@v4Xq{=Jos|cBs;dYkx@NO%EE6p1K+-1M(^a(tKUDczJWszz6E?8exA?3;JWCH1 z(P%2Ygv4zy#N4p3Fau=JHo6JT8%Y$VW4aga`|crh%&+|wfDHz^tMhlbk^X#1jYl0O zuyPaF@Cmd|i{|#qRRrfa*L(t|-9P-sEZKHAJEq&|-Mk5l0Pe#l*nzblSRYMI;YUZj ztgc>;N6h7$q6O|>C!2M5qYOjq*$UY_aT^RV2b#wWR`crM_aJ*TzL5fLHsGst@}w*K z7J(GP-Z;aB#$3rRxSCzSMSwG#@#r~ZnTeGbMeGA~)3sO#nNS3}sFknsg)0e`E4$1u zh|aa#r^9CTTUpCMT^j@03UM0@F#}p5(#=kK45D1D6#!!Ab^=ST9EdqgYr($!3RL*B zMd6_Z@*7KI-w?OKkVp^SCDP4rTtjgYh>+9Mx!44|TK89=vgn)?t8@DCCUE}>6bW3r zyIO{!HL*{K+hB+}&GKH9W-kj|}lHCI>>@BB-Mk*{q?s zO;}}OeXKKEf@54@zwBHKE?i@A3Kvl5fkKcufj%$;4#AQMxs1r2Nce!ng0g%F#e-YP z#$>XWA2b<1J9OxgqEw zVA=L9`u9!r+NzD~0lj$lLor9V@KCgTB3iyce(mn1G7PO?;j-o8Heqp!H4aNz`iHdl zW6Tc;Ks($F(Fa1g|!5P@K7ccdn>5)}F`U71-Um4HQVgV=VTi zS&MEhZonV7jmVOqX_8B25{AXKDC-mLcYh;3didosooAzlF@I6Zo`G)sZ{Y7<{80W5 za2($y8J&&lYV0@ox$}6{Q1!(lxZv@`l1lP;zXjxB-%ez1F}9DNzXRv?5%@b$t&h*& z-2=T|j5D$(&=|$~@8IutXU4bU)8X%K!Z(NnpCW%Z#Qa2DH+;ePyJhDjj)XW4^pofB z`kEj6ujKErT>K;QcN@M){M}tx(3L>y{x9%%pr@Y@f46MdCp^!8GW^}{ucOxv$KPR& z`1t(YDwh7=$KP%FnyB_C!r$G3vOZh>uD}=qcWL9`P0(|4|BI+TZ`xEZm!v!;*FWpn zu;D8Bw0g3-g%4dt8{LYjK_6}t4<5Ytck!Duor zhi7IA{p4+1Ajs|z>!Y}01Fq#^vE`cSw|qeQEyJaqTds9;eH9#+v0zQhg6sTy%gz*P z&z;6_$gFbl6<4l_l8(66TCOtd^4)OQ1z0+Egqp4er@G+!4srfuEr>Ohf$Q;0hyNO+ zdTa#fvNi&QQd@º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