lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] sequence input editor -- how to get accepted keywords


From: Greg Chicares
Subject: Re: [lmi] sequence input editor -- how to get accepted keywords
Date: Wed, 02 Jun 2010 12:30:50 +0000
User-agent: Thunderbird 2.0.0.24 (Windows/20100228)

On 2010-06-01 16:43Z, Vaclav Slavik wrote:
> On Thu, 2010-05-13 at 17:38 +0000, Greg Chicares wrote:
>> for new types as in this very rough sketch:
>> 
>>   class mode_sequence : public datum_sequence {
>>     // ...forwarding for whatever we need from base class...
>>     virtual std::map const& keywords
>>       {...transplant code from Input::RealizePayment() here...} 
> 
> the trouble with this is that the list of allowable keywords depends on
> other Input values -- SolveType in particular. Is that something that
> should be moved to RealizeXXX() (making permission_*_keywords()
> functions of respective field's type only)?

It's a general problem inherent in the problem domain: any Input field
may depend on all other Input fields. From the MVC documentation in
'mvc_controller.hpp':

/// Model: A class that contains all input parameters as data members,
/// and implements all problem-domain rules. Parameters are UDTs that
/// know what values are valid (date within some range, e.g.). One
/// control's valid range or enablement may depend on another's value;
/// member functions work with the parameter UDTs to handle that. One
/// could wish for a prolog inference engine integrated with C++,
/// because this is all about backward chaining over Horn clauses.
///
/// Each UDT embodies the desired enablement state of the associated
/// control. Each numeric UDT embodies a range of allowable values.
/// Each enumerative UDT embodies a subset of allowable enumerators.
/// Collectively, these properties embody the problem-domain rules.

Here, we'd add something like "Each sequence UDT that permits keywords
embodies a subset of allowable keywords".

/// When control values change, the Controller passes them to the
/// Model. The Model validates the change (described separately below)
/// and updates its UDT members to reflect enablement and constraints
/// on numeric ranges or enumerator allowability. Then the Controller
/// updates the View to correspond to the updated Model, potentially
/// changing indicia of enablement or of constraints (such as the
/// choices available in a wxComboBox) as well as values in the View.

[The 'skeleton' trunk
  http://svn.savannah.nongnu.org/viewvc/skeleton/trunk/?root=lmi
applies (an older version of) the same MVC code to a problem domain
that's easier to grasp because it avoids insurance concepts. All of
the tabs on its "Miscellaneous | Properties" dialog are relevant here,
especially the one that demonstrates the effect of dietary restrictions
on an abbreviated restaurant menu. The 'skeleton' patch below [0] is
needed for wx-2.9 . Returning to lmi...]

Here's an annotated example from Input::DoHarmonize() that demonstrates
a relationship among enumerative types:

    // This flag depends on the value of an Input data member.
    bool blend_mortality_by_gender = mce_yes == BlendGender;
    // This flag depends on the product database, which in turn depends
    // (via Input::DoAdaptExternalities()) on half a dozen Input data
    // members.
    bool allow_gender_distinct = database_->Query(DB_AllowSexDistinct);
    // Both flags affect whether Gender can be "Female".
    Gender.allow(mce_female, !blend_mortality_by_gender && 
allow_gender_distinct);

That's the place where such dependencies are generally resolved...for
everything except input sequences. Sequences are an exception only
because I didn't have time to do the right thing years ago. I think
the conditional code for sequence keywords belongs in DoHarmonize():

http://lists.nongnu.org/archive/html/lmi/2010-05/msg00015.html
| This conditional code:
|
|   std::string Input::RealizePayment()
|   {
|       std::map<std::string,std::string> z = 
permissible_payment_strategy_keywords();
|       if(mce_solve_ee_prem == SolveType)
|           {
|           z.clear();
|           }
|
| needs to be moved into Input::DoHarmonize()

Thus, today we have
  Input::permissible_death_benefit_option_keywords()
that returns a container that includes every possible keyword, and
  Input::RealizeDeathBenefitOption()
which produces an error message for keywords that are possible in
general but forbidden in the current context...and then realizes the
input sequence. Instead, I'm proposing
  a new UDT (e.g., 'dbo_sequence')
that "knows" the list of every possible keyword (just as type mce_dbopt
"knows" all its possible values) and provides a function (like type
mce_dbopt's allow() function) to modify each keyword's "allow" bit;
and modifications to
  Input::DoHarmonize()
that use that function to set those "allow" bits; and then we can
completely remove
  Input::permissible_death_benefit_option_keywords()
which will no longer be necessary, and then
  Input::RealizeDeathBenefitOption()
can be reduced to just enough code to realize the sequence, with
the conditional code it now contains moved to Input::DoHarmonize().
It no longer needs to test those conditions, because an input
string has to be accepted by DoHarmonize() before it can be passed
to the 'Realize' functions.

Does that answer your question? Repeating it:

> the trouble with this is that the list of allowable keywords depends on
> other Input values -- SolveType in particular. Is that something that
> should be moved to RealizeXXX() (making permission_*_keywords()
> functions of respective field's type only)?

I envision a UDT that, upon construction, knows all the permissible
keywords independent of context--with a member function to enforce
contextual restrictions as the context changes.

---------

[0] "The 'skeleton' patch below"

Apply this to:
  http://svn.savannah.nongnu.org/viewvc/skeleton/trunk/?root=lmi
(not to:
  http://svn.savannah.nongnu.org/viewvc/lmi/trunk/?root=lmi
to which it has already been applied).

Index: alert_wx.cpp
===================================================================
--- alert_wx.cpp        (revision 4730)
+++ alert_wx.cpp        (working copy)
@@ -159,7 +159,7 @@
             handle = reinterpret_cast<HWND>(top_window->GetHandle());
             }
         }
-    ::MessageBox(handle, message, "Error", MB_OK | MB_ICONSTOP | MB_TASKMODAL);
+    ::MessageBoxA(handle, message, "Error", MB_OK | MB_ICONSTOP | 
MB_TASKMODAL);
 #endif // defined LMI_MSW
 }





reply via email to

[Prev in Thread] Current Thread [Next in Thread]