.NET 自然语言编程/别名/(领域特定语言)框架
目前,我们使用 ILOG BRMS for .NET 来允许业务用户在我们的系统中创建逻辑,而无需了解如何编程。该规则由业务用户创建(即:它是系统的一部分,而不是规范的一部分):
definitions
set 'the letter event' to the scheduled DelinquentLetterEvent on the invoice;
set 'final notice possibility1' to the bill date of the invoice + 36 days;
set 'final notice possibility2' to the time of 'the letter event' + 7 days;
set 'final notice result' to the most future date from these values {
'final notice possibility1', 'final notice possibility2' };
then
in the event that 'final notice result' is not a mailing date,
change it to the next available mailing date;
add a new FinalNoticeEvent scheduled for 'final notice result' to the invoice;
系统在 .Net 中执行等效操作(此处显示伪 C#):
//variable declarations
ScheduledEvent theLetterEvent = theInvoice.GetScheduledEvent(
KnownEventType.DelinquentLetterEvent);
DateTime noticePossibility1 = theInvoice.BillDate.AddDays(36);
DateTime noticePossibility2 = theLetterEvent.Time.AddDays(7);
DateTime[] possibilities = new DateTime[]()
{ noticePossibility1, noticePossibility2 };
DateTime noticeResult = CustomClass.Max(possibilities);
//actions
CustomClass2.MakeNextMailingDate(ref noticeResult);
theInvoice.AddScheduledEvent(KnownEventType.FinalNoticeEvent, noticeResult);
程序员在设计时指定使用什么文本对于每个类/方法/属性。例如,最后一个方法的文本是:
add a new {0} scheduled for {1} to {this}
我慢慢意识到我根本不需要 BRMS。将规则与断言实例相匹配的概念对于业务用户和程序员来说都是陌生的。我们的业务用户对 SQL 脚本有些熟悉(有些人了解一点 VBA),因此他们对顺序执行感到满意。
我真正想要的是一种在设计时指定文本的方法(DSL),该方法映射到自然语言编程的类/方法/属性,最好是在 BRMS 之外。
这样的事存在吗?这个概念的正确名称是什么?
回应:
我们已经考虑使用脚本语言来广泛满足这一需求。具体来说,他们不提供我所寻求的到 .NET 代码的文本替换/映射。 我想编写 ac# 方法,然后声明一些可以调用它的合理短语。
ANTLR - 谢谢你的提示。这是一个通用解析器。如果我想自己实现这个,毫无疑问我需要一个解析器。
根据定义,您使用针对问题领域的生硬词汇发明的任何人工语言都是“特定领域语言”。
我觉得这个陈述对于我的问题来说是一个很好的答案。谢谢。
如果您需要完全通用的计算,您最终将得到一种典型的计算机语言。如果您可以大大缩小范围,您可能会得到一些有用的东西。
我可以将范围缩小到调用我已实现的方法,但问题是,当我添加更多方法时,我想为这些新方法附加更多词汇。
无论我们继续使用 ILOG 还是其他东西作为该语言的支持基础设施,DSL 都会不断发展。
We currently use ILOG BRMS for .NET to allow business users to create logic in our system without knowing how to program. This rule is created by a business user (ie: It's a part of the system, not a part of the specification) :
definitions
set 'the letter event' to the scheduled DelinquentLetterEvent on the invoice;
set 'final notice possibility1' to the bill date of the invoice + 36 days;
set 'final notice possibility2' to the time of 'the letter event' + 7 days;
set 'final notice result' to the most future date from these values {
'final notice possibility1', 'final notice possibility2' };
then
in the event that 'final notice result' is not a mailing date,
change it to the next available mailing date;
add a new FinalNoticeEvent scheduled for 'final notice result' to the invoice;
The system performs the equivalent in .Net (here showing psuedo C#):
//variable declarations
ScheduledEvent theLetterEvent = theInvoice.GetScheduledEvent(
KnownEventType.DelinquentLetterEvent);
DateTime noticePossibility1 = theInvoice.BillDate.AddDays(36);
DateTime noticePossibility2 = theLetterEvent.Time.AddDays(7);
DateTime[] possibilities = new DateTime[]()
{ noticePossibility1, noticePossibility2 };
DateTime noticeResult = CustomClass.Max(possibilities);
//actions
CustomClass2.MakeNextMailingDate(ref noticeResult);
theInvoice.AddScheduledEvent(KnownEventType.FinalNoticeEvent, noticeResult);
Programmers specify at design time what text is used for each class/method/property. For example, the text for that last method is:
add a new {0} scheduled for {1} to {this}
It's slowly dawning on me that I don't need a BRMS at all. The concept of matching of rules to asserted instances is just as alien to business users as it is to programmers. Our business users are somewhat familiar with SQL scripting (and some know a bit of VBA), so they are comfortable with sequential execution.
What I really want is a way to specify text at design time (a DSL) that maps to classes/methods/properties for natural language programming, preferably outside of a BRMS.
Does such a thing exist? What is the proper name for this concept?
Responses:
We have considered scripting languages to fill this need broadly. In specific, they do not offer the text substitution/mapping to .NET code that I seek.
I want to write a c# method, then declare some sensible phrases by which one might invoke it.
ANTLR - thanks for the tip. This is a generic parser. I will no doubt require a parser if I want to implement this myself.
Any artificial language you invent with a stilted vocabulary focused in a problem area is by definition a "domain specific langauge".
I feel this statement is as good as an answer as I can get to my questions. Thanks.
If you need fully general computation, you're going to end up with a typical computer language. If you can narrow the scope a lot, you might end with something useful.
I can narrow the scope all the way down to calling the methods I've implemented, but the catch is that as I add more methods, I want to attach more vocabulary for those new methods.
The DSL will evolve whether we continue to use ILOG or something else as the supporting infrastructure for the language.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
实际上,您无法编写一个接受真正的自然语言并将其映射到工作代码的工具。没有人知道如何做到这一点。 (因此用 C# 而不是英语)。
您所能期望的最好的结果是一组生硬的短语(很像您展示的 BRML),它总是具有更好定义的优点,并且对于“业务用户”来说更难学习,因为他们不(想要) )知道该说什么开始,更不用说表达的限制是什么了。根据定义,您使用针对问题领域的生硬词汇发明的任何人工语言都是“特定领域语言”。
真正的争论是,您的语言需要涵盖哪些活动范围?您的“业务”用户的受教育程度如何(如果他们可以编码,我想知道他们作为“业务用户”的特征)?他们是否同意他们愿意说的事情范围(我打赌不会)。如果你需要完全通用的计算,你最终会得到一种典型的计算机语言(实际上更糟糕,因为你最终会在编程功能上陷入沙堡,产生一个真正丑陋的婴儿)。如果你能大大缩小范围,你可能会得到一些有用的东西。
问题是,您能否设计这样一种语言,它比您打算取代的 BRML 更好,满足用户期望的功能? [我对 ILOG 的 BRML 有多好没有意见,但你必须假设他们已经尝试解决这个问题一段时间了,并且由于它们仍然存在,所以他们一定没有一个愚蠢的解决方案]。
如果您有信心可以,那么您可以使用基于解析器的代码生成器工具来实现 DSL。这完全是一个实验;如果你现在开始,一年内你都不会知道你的方法是否成功,而且可能会失败。
良好的语言设计,无论是过程语言还是 DSL,都是困难。
可行的 DSL 通常会发生的情况是,它们设法解决原始问题中有趣的部分,而让其余部分“以某种方式”解决。解决这个问题的一种方法是发展 DSL:新语法、新语义等;成功的 DSL 确实会发生这种情况。期待你的也能发展。另一种典型的方法是提供一些标准转义机制(例如,某种过程调用、任意表达式……),然后有人根据需要添加额外的子例程。
即使您获得了正确的 DSL,它也可能不会被社会接受。 [Ada 是一种非常好的语言,它被 C 和 C++ 取代,因为程序员根本不想学习它]。
As a practical matter, you can't write a tool that accepts real natural language and maps it to working code. Nobody knows how to do this. (Hence C# instead of English).
The best you can hope for is a stilted set of phrases (much like the BRML you exhibited), which always has the advantage of being better defined, and a lot harder for "business users" to learn because they don't (want to) know what to say to start, let alone what the limits of expressiveness are. Any artificial language you invent with a stilted vocabulary focused in a problem area is by definition a "domain specific langauge".
The real arguments are, what range of activities does your language need to encompass? How educable are your "business" users (if they can code, I wonder about the characterization of them as "business users")? Do they agree on the range of things they are willing to say (bet not). If you need fully general computation, you're going to end up with a typical computer language (actually worse, because you'll end up sandcastling on programming features, producing a truly ugly baby). If you can narrow the scope a lot, you might end with something useful.
The question is, can you design such a language, which is better than the BRML you intend to displace, for what the users expect to be able to do? [I have no opinions about how good ILOG's BRML is, but you have to assume they've been trying to solve this problem for awhile, and since they still exist, they must not have a stupid solution].
If you are confident you can, then you can use parser-based code generator tools to implement the DSL. Its quite the experiment; if you start now you won't know for a year if your approach is successful, and it might fail.
Good language design, whether procedural, or DSL, is hard.
What usually happens with workable DSLs is they manage to address an interesting part of the original problem, leaving the rest to address "somehow". One way to handle this is to evolve the DSL: new syntax, new semantics, etc.; this does happen with successful DSLs. Expect yours to evolve, too. Another typical way is to provide a few standard escape mechanisms (e.g., some kind of procedure call, arbitrary expressions, ...) and then somebody adds extra subroutines on demand.
Even you get the DSL right, it may not become socially accepted. [Ada was a really good language, and it got displaced by C and C++ because the programmers simply didn't want to learn it].
对于如何实现这一目标,您有多种选择。让我们举几个例子:
集成脚本语言。例如,您可以使用 VBScript 或 Lua。您为自己的对象创建包装器并使它们可供脚本语言使用。这样做的好处是已经为您实现了解析器和可执行引擎;
使用 XAML。 XAML 是一种在 XML 中定义对象结构的方法。您可以使用公式的标记扩展,以便可以使用例如
BillDate="{DateFormula +1 days}"
;使用 XAML 来指定日期
使用 ANTLR 为您自己的 DSL 定义解析器。使用 ANTLR,编写解析器相对容易。您可以根据匹配的构造在语法中创建对象。
You have many choices on how to accomplish this. Let's name a few:
Integrate a scripting language. You can e.g. use VBScript or Lua. You create wrappers for your own objects and make them available to the scripting language. The advantage of this is that a parser and executable engine have already been implemented for you;
Use XAML. XAML is a way to define object structures in XML. You can use the markup extensions for formulas so you can assign a date using e.g.
BillDate="{DateFormula +1 days}"
;Use ANTLR to define a parser for your own DSL. With ANTLR, it's relatively easy to write a parser. You can create the objects in your grammar from the matched constructs.