AI Zone Admin Forum Add your forum

NEWS: Chatbots.org survey on 3000 US and UK consumers shows it is time for chatbot integration in customer service!read more..

how to write a rule with a concept which can be set or queried
 
 

For my use case, I would like to write a general rule containing a concept, but the concept shall be different or changeable per query.

Firstly, I tried to assign it to a variable.

u: ()
$var = ~concept_1

u: ($var)
I wish this equals to u:(~concept_1), but it does not.

Then, I tried to put it to a table, and I made a query. It does not work neither.

table: mytbl ()
^createfact(mysub myverb ^concept_1)

topic: mytopic []
u: ()
@9 = ^query(direct_sv mysub myverb ?)
u: (@9object)
does not work neither.

Is there a good solution or alternative?

 

 

 
  [ # 1 ]

There are a couple of options:

u: (_*1)
  if (!^query(direct_svo _0 member $var)) { ^retry(RULE) }


u: ()
  @0 = ^conceptlist(CONCEPT null $var)
  if (^length(@0) == 0) { ^fail(RULE) }

The first one grabs a word and checks to see if it is a member of your query. If not then the rule is retried, which means that CS will grab the next word. This style can be tricky for concept members that are more than one word.

The second option returns a fact set with all the marked words from the sentence (that is the null) and which have your concept name as the leading part of the marked concept. Obviously if there your concept name is not a prefix of any other then you have those that are an exact match. The subject of the facts is the actual matching concept, so that can always be tested against.

 

 
  [ # 2 ]

And a third option is:

u: ()
  $_pat = ^join( \” _ ~ concept _ 1 \” )
  if (!^match($_pat)) { ^fail(RULE) }

 

 
  [ # 3 ]

Thanks, Andy.  I have chosen option 2, but that only solves half of my problem.

After I get the concept, I would like to match it. But the compiler does not allow such thing, like

u: (_@0subject)

Then I tried to assign it to a variable, like
$$cpt = @0subject

u: (_$$cpt)
_0

The rule works, but the matching does not happen. Is this a bug or some kind of design intention? Any solution for this?

 

 
  [ # 4 ]

There is no need to have another rule, all of these options give you enough to work with.

The first option has already matched a word, so you can go from there.
Conceptlist returns the position of the match in the fact object. You can decode that (start = @0object >> 8 end = @0object %  256) and then use ^wordAtIndex() to get the words.
The third option with the dynamically constructed pattern and ^match() will give you the matched words directly in _0.

What else do you need to do?

 

 
  [ # 5 ]

Thanks for the explanation, Andy.

I do have one related question. After I got an concept $my_cpt. It’s type is concept, not a string.

How can I get back the concept name (or the string representation) using $my_cpt.

Since ^length($my_cpt) returns the number of first level members of the concept. But I actually would like to get the length of the concept name. I would like to access the name, as I need to obtain certain info from the name.

 

 
  [ # 6 ]

There’s no real type of concept, your variable will contain a string that just so happens starts with a ~ and so certain functions will process it as a concept, such as ^length() as you’ve seen.
If you want to process the concept name for what it is then your options depend on how the name is structured.

If it is just a sequence of characters with no pattern, then just use ^extract() to extract everything beyond the leading ~. You can use a bogus length like 999 (CS will automatically use the real length).

Alternatively if your concept name has some kind of separator character between segments, then use ^burst() to split the string up.

I’ve used both approaches in various scenarios.

 

 
  [ # 7 ]

Thanks a lot, Andy. This answers lots of my doubts, and I tried burst(), it works like a charm for me.

I wish the documents could explain some of these details a little bit more, especially some internals.

 

 
  login or register to react