FYI – I posted Mike's nice summary to this
page<https://wiki.openmrs.org/x/G4GxAQ>on the wiki and added a comment
to cover some outstanding issues, including
those brought up by Win & Steve.  Anyone interested can watch that page
(I've already added a few watchers).  If you think of any additional
issues/questions that need to be addressed in coming up with a "final" lit
of requirements for logic 2.0, please add your comment(s) to the bottom of the
page <https://wiki.openmrs.org/x/G4GxAQ>.

We'll discuss logic again on a design call in a couple weeks.

Cheers,

-Burke

On Thu, Nov 17, 2011 at 8:34 AM, Nyoman Ribeka <[email protected]> wrote:

> To chip in:
>
> I would rather us to have something like:
>
> - EvaluationParameter instead of Map<String, Object> as the rule
> evaluation parameter.
> - EvaluationResult instead Map<Integer, Result>.
>
> Definitely need to do another design call.
>
> On Wed, Nov 16, 2011 at 5:47 PM, Darius Jazayeri
> <[email protected]> wrote:
> > Perhaps we should revisit this on the design call in 2 weeks?
> > -Darius
> >
> > On Wed, Nov 16, 2011 at 2:14 PM, Michael Seaton <[email protected]> wrote:
> >>
> >> Hi all,
> >>
> >> Thanks to everyone who participated in this call today - I think we
> made a
> >> lot of progress.  Here is a summary of what we were able to produce
> (full
> >> etherpad notes here):
> >>
> >> Requirements/Goals
> >>
> >> Existing logic engine can be implemented as an optional module without
> too
> >> much trouble.
> >> A shared Rule interface
> >>
> >> Rules provide a method to evaluate within a context + parameters
> >>
> >> A shared Result interface
> >>
> >> Result declares it's type explicitly
> >> Provides a mechanism for consumers to easily distinguish between & use
> >> lists vs. single values
> >>
> >> Provides an easy way to coerce results between different types and
> between
> >> lists vs. single value
> >> A shared LogicContext interface within which rules are evaluated
> >> Centralized token registration by providing token, rule ID, provider,
> and
> >> configuration (unique across providers)
> >> Support for parameters.
> >> Caching is deferred to rule evaluators for now
> >>
> >> Skeleton Interfaces / Implementations
> >>
> >> Rule:
> >>
> >> interface Rule {
> >>   public Set<RuleParameterInfo> getParameterList();  // TODO: We didn't
> >> discuss this interface, but we did agree that rules need to support
> >> parameters
> >> }
> >>
> >> interface RuleEvaluator {
> >>   boolean canEvaluate(Rule rule);  // TODO: This might be better
> >> implemented through annotations.  Needs further discussion
> >>   Map<Integer, Result> evaluate(Cohort, Rule, Map<String, Object>,
> >> RuleContext); // TODO: We probably want to wrap Map<Integer, Result> in
> a
> >> proper class
> >> }
> >>
> >> interface RuleProvider {
> >>   Rule getRuleInstance(String ruleName, String extraConfig); // ruleName
> >> could be anything the provider wants.  might typically be a classname.
> >> }
> >>
> >> interface / implementation RuleService/RuleServiceImpl {
> >>   RuleContext createContext(); // Ensures that RuleContext can be
> >> overridden as needed
> >>   void registerToken(String token, RuleProvider provider, String
> ruleName,
> >> String extraConfig);
> >>   void unregisterToken(String token, RuleProvider provider); // provider
> >> for safety
> >>
> >>   (the below methods might also have implementations without RuleContext
> >> and/or without params for convenience)
> >>   Result evaluate(Integer ptId, String token, Map<String, Object>
> params,
> >> RuleContext context) {
> >>     // create a cohort with a single patient, call the evaluate method
> on
> >> the cohort, return the result for that patient
> >>   }
> >>   Map<Integer, Result> evaluate(Cohort c, String token, Map<String,
> >> Object> params, RuleContext context) {
> >>     // find the appropriate RuleProvider, ruleName, extraConfig for the
> >> given token; get the Rule from the RuleProvider passing in the ruleName
> and
> >> extraConfig; call evaluate method on the Rule
> >>   }
> >>   Result evaluate(Integer ptId, Rule rule, Map<String, Object> params,
> >> RuleContext context) {
> >>     // construct a cohort of one; get the evaluator for the passed rule;
> >> call evaluate passing in the cohort, params and the context; return the
> >> result for the patient
> >>   }
> >>   Map<Integer, Result> evaluate(Cohort c, Rule rule, Map<String, Object>
> >> params, RuleContext context) {
> >>     // get the evaluator for the passed rule; call evaluate passing in
> the
> >> cohort, params and the context; return the result
> >>   }
> >> }
> >>
> >> interface RuleContext {
> >>   // TODO: Figure out whether this has indexDate, any caching, etc.
> >> }
> >>
> >> Result:
> >>
> >> interface Result {
> >>   public Object getValue();
> >>   public Date getDatetime(); // Needs more discussion if this is
> >> appropriate on the base interface (eg. what to do for Lists)
> >>   public String formatAsString();
> >> }
> >>
> >> class NumericResult {
> >>   private Double result;
> >>   private Date datetime;
> >>   public Object getValue() { return result; }
> >>   public Date getDatetime() { return datetime; }
> >> }
> >>
> >> class ListResult {
> >>   private List<Result> results;
> >>   public Object getValue() { return results; }
> >>   public Date getDatetime() { // Not sure what to do here.  Get the
> >> datetime of the first result?  Maybe this method doesn't belong
> >> }
> >>
> >> class ObsResult {
> >>   private Obs obs;
> >>   public getValue() { return obs; }
> >>   public Date getDatetime() { return obs.getObsDatetime(); }
> >> }
> >>
> >> Use of Result:
> >>
> >> For coercing / converting Results to scalars for use in comparisons etc,
> >> for example:
> >> if (eval("BMI") > 23) { ... }, we discussed a few possible approaches:
> >> (TODO:  Decide on one)
> >>
> >> 1. adding methods like "asDouble()", "asDate()", "asString()",
> >> "asBoolean()" to the Result interface (as we have now)
> >> 2. Add single method to Result like:  eval("BMI").coerce(Double.class) >
> >> 23
> >> 3. Add utility method like:  LogicUtil.toDouble(eval("BMI")) > 23
> >> 4. Add utility method like:  LogicUtil.coerce(eval("BMI"),
> Double.class) >
> >> 23
> >> 5. Add a variety of converters like:  new
> >> DoubleConverter().convert(eval("BMI")) > 23
> >>
> >> Benefit of #5 is that it is cleaner than a massive utility method with
> >> lots of conditional logic, and that it allows modules to plug new
> converters
> >> into the framework as needed.  It might look something like this:
> >>
> >> interface ResultConverter<T> {
> >>   public T convert(Result);
> >> }
> >>
> >> class DoubleConverter<Double> {
> >>   public Double convert(Result result) { return
> >> Double.valueOf(result.toString()); }
> >> }
> >>
> >>
> >> We ran out of time before we could really discuss next steps on all of
> >> this.  Should we carve out time in another design forum in December?
> >>
> >> Thanks,
> >> Mike
> >>
> >>
> >>
> >>
> >> On 11/16/2011 03:23 AM, Ben Wolfe wrote:
> >>
> >> Lets plan on having a discussion today about this on the design call at
> >> 2pm.  We can write up the solutions (and new questions) for Tammy to
> read
> >> offline.
> >>
> >> Ben
> >>
> >> On Tue, Nov 15, 2011 at 2:21 PM, Dugan, Tammy Marie <[email protected]>
> >> wrote:
> >>>
> >>> I am on maternity leave and have my hands pretty full with a two week
> old
> >>> and a two year old. If you have any specific questions, please feel
> free to
> >>> email me. Email is a lot easier for me right now than phone.
> >>>
> >>> Thanks,
> >>>
> >>> Tammy Dugan
> >>>
> >>> Quoting Michael Seaton <[email protected]>:
> >>>
> >>>> Yes, I will be there and looking forward to talking about this.
> >>>>
> >>>> Mike
> >>>>
> >>>> From: [email protected] [mailto:[email protected]] On Behalf Of Ben Wolfe
> >>>> Sent: Tuesday, November 15, 2011 3:14 AM
> >>>> To: [email protected]
> >>>> Subject: Re: [OPENMRS-DEV] The future of Logic
> >>>>
> >>>> Would it be possible for folks to join tomorrow the 16th at 2pm EST?
> >>>> I fear that some people will be missing next Wednesday due to the US
> >>>> holiday on Thursday the 24th.
> >>>>
> >>>> Tammy? Dave? Mike? Darius? Burke? Roger? Win? Beuller?
> >>>>
> >>>> https://wiki.openmrs.org/display/RES/Design+Forum
> >>>>
> >>>> Ben
> >>>> On Mon, Nov 14, 2011 at 8:55 PM, Burke Mamlin
> >>>> <[email protected]<mailto:[email protected]>> wrote:
> >>>> Can we enumerate what we want from the simplified logic service?
> >>>>
> >>>> *   Existing logic engine can be implemented as an optional module
> >>>> without too much trouble.
> >>>> *   Strongly instead of loosely typed results.
> >>>> *   Support for parameters.
> >>>> *   ...
> >>>> Do we want to support an index date (i.e., avoid assuming today's
> date)?
> >>>>
> >>>> Don't we want to forego tokens?  Or are we assuming that consumers of
> >>>> logic know which rule provider to consult (which may or may not use
> >>>> tokens)?  If the consumer needs to know which provider to consult and
> >>>> that provider will presumably be handling the evaluation, then what
> >>>> purpose does the logic service serve?  Alternatively, rule providers
> >>>> could be registered with the logic service and then consumers could
> >>>> come to the logic service with a token (i.e., not need to know the
> >>>> provider).
> >>>>
> >>>> I'm assuming that we'll defer caching & criteria implementations to
> >>>> the various forms of logic (at least for now).
> >>>>
> >>>> What's the purpose of LogicContext now?  In the original design,
> >>>> LogicContext served a few purposes: (1) proxy for all data requests
> >>>> by rules, (2) provide a context for evaluations ? index date &
> >>>> parameters ? that could be stacked for recursion, (3) context for
> >>>> caching results, and (4) an abstraction so that the same rule could
> >>>> be run against a patient or cohort.  If we aren't using logic context
> >>>> for any of these, do we need to maintain LogicContext at this stage?
> >>>>
> >>>> Looking forward to the design call.
> >>>>
> >>>> Cheers,
> >>>>
> >>>> -Burke
> >>>>
> >>>> On Wed, Nov 9, 2011 at 10:23 PM, Michael Seaton
> >>>> <[email protected]<mailto:[email protected]>> wrote:
> >>>> Hi all,
> >>>>
> >>>> I wanted to pick up a thread on the future of Logic that we spent
> >>>> some time discussing during the Developers Forum on October
> >>>> 27<https://wiki.openmrs.org/x/5oamAQ>.
> >>>>
> >>>> The overall consensus on the call was that "Logic is too complicated.
> >>>> We wish there were a simpler implementation, that were easier to
> >>>> adapt to individual needs.  We wish it were more rigorously tested,
> >>>> including performance testing".
> >>>>
> >>>> Anyone that cares about preserving Logic as it currently exists, or
> >>>> wants to see it change in a specific way, please read further
> >>>>
> >>>> Specific users of Logic have communicated the following needs:
> >>>>
> >>>> *   Tammy and her team require more control over the current Logic
> >>>> implementation, and better testing around it, so that future upgrades
> >>>> do not cause serious bugs and performance degradation
> >>>> *   Win and Tammy need implementations of Logic that are optimized
> >>>> for running lots of rules for individual patients at a time
> >>>> *   Mike needs an implementation of Logic that is optimized for
> >>>> running a single rule for lots of patients at a time as well
> >>>> *   Mike wants to be able to choose to not use the existing Logic
> >>>> implementation in favor of an implementation provided by the
> >>>> Reporting module
> >>>> To accomplish this, the following high-level refactoring steps are
> >>>> being considered:
> >>>>
> >>>> *   Reduce and simplify the number of interfaces and interface
> >>>> methods that Logic exposes in OpenMRS core
> >>>> *   De-couple the existing Logic Module in such a way that it is one
> >>>> of many possible "Rule Providers" that can plug into this
> >>>> lighter-weight core framework
> >>>> *   Remove, if possible and practical, the need to have a "required"
> >>>> Logic module installed
> >>>> Specifically, we are considering an approach that would reduce the
> >>>> core Logic interfaces to something like:
> >>>> interface LogicContext;
> >>>>
> >>>> interface Result; (classes DateResult, NumberResult, ListResult...)
> >>>>
> >>>> interface Rule {
> >>>>  Set<RuleParameterInfo> getParameterInfo();
> >>>>  Class<? extends Result> getReturnType();
> >>>>  Result evaluate(Integer patientId, Map<String, Object> parameters,
> >>>> LogicContext context);
> >>>> }
> >>>>
> >>>> interface LogicService {
> >>>>  public Result evaluate(Rule rule, Patient patient, Map<String,
> >>>> Object> parameters, LogicContext context);
> >>>>  public Map<Integer, Result> evaluate(Rule rule, Cohort cohort,
> >>>> Map<String, Object> parameters, LogicContext context);
> >>>> }
> >>>> I would like for this to spur the following potential activities:
> >>>>
> >>>> *   Give anyone who has not yet been aware of these discussions, or
> >>>> who does not agree with this approach, an opportunity to weigh in and
> >>>> get involved in the process
> >>>> *   Make a plan to put this topic onto one or more future Design
> >>>> Forum calls, in order to agree upon the revised design, make tickets,
> >>>> and establish an owner for moving it forward.
> >>>> *   Publicize when this Design Forum will occur so that interested
> >>>> parties can be involved as desired
> >>>> Thanks!
> >>>> Mike
> >>>>
> >>>>
> >>>> ________________________________
> >>>> Click here to
> >>>>
> >>>> unsubscribe<mailto:[email protected]
> ?body=SIGNOFF%20openmrs-devel-l>
> >>>> from OpenMRS Developers' mailing
> >>>> list
> >>>>
> >>>> ________________________________
> >>>> Click here to
> >>>>
> >>>> unsubscribe<mailto:[email protected]
> ?body=SIGNOFF%20openmrs-devel-l>
> >>>> from OpenMRS Developers' mailing
> >>>> list
> >>>>
> >>>> ________________________________
> >>>> Click here to
> >>>>
> >>>> unsubscribe<mailto:[email protected]
> ?body=SIGNOFF%20openmrs-devel-l>
> >>>> from OpenMRS Developers' mailing
> >>>> list
> >>>>
> >>>> _________________________________________
> >>>>
> >>>> To unsubscribe from OpenMRS Developers' mailing list, send an e-mail
> >>>> to [email protected] with "SIGNOFF openmrs-devel-l" in the
> >>>> body (not the subject) of your e-mail.
> >>>>
> >>>> [mailto:[email protected]?body=SIGNOFF%20openmrs-devel-l]
> >>>>
> >>>
> >>> _________________________________________
> >>>
> >>> To unsubscribe from OpenMRS Developers' mailing list, send an e-mail to
> >>> [email protected] with "SIGNOFF openmrs-devel-l" in the
>  body (not
> >>> the subject) of your e-mail.
> >>>
> >>> [mailto:[email protected]?body=SIGNOFF%20openmrs-devel-l]
> >>
> >> ________________________________
> >> Click here to unsubscribe from OpenMRS Developers' mailing list
> >>
> >> ________________________________
> >> Click here to unsubscribe from OpenMRS Developers' mailing list
> >
> > ________________________________
> > Click here to unsubscribe from OpenMRS Developers' mailing list
>
>
>
> --
> Thanks,
>
> Nyoman Ribeka
>
> _________________________________________
>
> To unsubscribe from OpenMRS Developers' mailing list, send an e-mail to
> [email protected] with "SIGNOFF openmrs-devel-l" in the  body
> (not the subject) of your e-mail.
>
> [mailto:[email protected]?body=SIGNOFF%20openmrs-devel-l]
>
>

_________________________________________

To unsubscribe from OpenMRS Developers' mailing list, send an e-mail to 
[email protected] with "SIGNOFF openmrs-devel-l" in the  body (not 
the subject) of your e-mail.

[mailto:[email protected]?body=SIGNOFF%20openmrs-devel-l]

Reply via email to