diff --git a/CHANGELOG.md b/CHANGELOG.md index 4057012b..c5f1f19f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,28 @@ As of v0.2-alpha, this project is attempting to adhere to [Semantic Versioning]( While alpha, however, any version may include breaking changes that may not be specifically noted as such, and breaking changes will not necessarily result in changes to the main version number. +## [v1.6.1-alpha](https://github.com/Lexpedite/blawx/releases/tag/v1.6.1-alpha) 2023-04-27 + +This release adds to the representational power of Blawx by adding "relationships", which are +a statement that is true (or not) about 3 or more objects or values. + +### Added +* Relationship Declaration Block +* Relationship Selector Blocks +* Known Relationship Drawer +* Associated documentation + +### Changed +* `/onto` endpoint returns information about relationships in addition to categories and attributes +* the JSON format accepted by the `test` and `interview` endpoints now accepts relationships in addition to categories and attributes +* The response from the ontology endpoint is now shown in the "devel" tab of the scenario editor. +* Scenario Editor has been modified to support relationships. +* Rock Paper Scissors example was updated to use relationships for throws instead of attributes. +* Associated documentation + +### Fixed +* Problems with natural language generation for non-boolean attributes in test editor explanations + ## [v1.6.0-alpha](https://github.com/Lexpedite/blawx/releases/tag/v1.6.0-alpha) 2023-04-11 **This release is NOT backward compatible.** diff --git a/blawx/fixtures/docs/blocks/categories/new_relationship.yaml b/blawx/fixtures/docs/blocks/categories/new_relationship.yaml new file mode 100644 index 00000000..afd565cf --- /dev/null +++ b/blawx/fixtures/docs/blocks/categories/new_relationship.yaml @@ -0,0 +1,35 @@ +- model: blawx.docpage + pk: blocks/new_relationship + fields: + title: New Relationship Block + content: | + # New Relationship Block + + ![New Relationship Block](/static/blawx/docs/images/blocks/new_relationship.png) + + ## Where Is It? + + The new relationship block is found in the Categories drawer of the Blawx toolbox. + + ## What Does It Do? + + The new relationship block is used to create a new relationship between 3 or more objects and values. + + ## Technical Details + + The new relationship block is a statement, and can be stacked with other statements. + + The new relationship block accepts the name of the relationship. To be valid, the name of the relationship must begin with a lower-case letter and not + include any spaces. + + It also accepts the number of objects and values that will be related to one another in this relationship, which + is a number between 3 and 10. + + For each object or value, it accepts a type, which is selected from a dropdown that shows the available data types and the known categories. + + Before, between, and after each object or value, it accepts the text that should be used to generate the relationship selector blocks, and used in + explanations. + + ## Tips + + Names of relationships should be unique, but can safely overlap with other relationship that have a different number of objects and values. \ No newline at end of file diff --git a/blawx/fixtures/docs/blocks/categories/relationship_selector.yaml b/blawx/fixtures/docs/blocks/categories/relationship_selector.yaml new file mode 100644 index 00000000..c5164df9 --- /dev/null +++ b/blawx/fixtures/docs/blocks/categories/relationship_selector.yaml @@ -0,0 +1,26 @@ +- model: blawx.docpage + pk: blocks/relationship_selector + fields: + title: Relationship Selector Block + content: | + # Relationship Selector Block + + ![Relationship Selector Block](/static/blawx/docs/images/blocks/relationship_selector.png) + + ## Where Is It? + + The relationship selector block is located in the Known Relationships drawer of the Blawx toolbox. + + ## What Does It Do? + + The relationship selector block is used to set or test a value for a relationship between 3 or more objects and values. + + ## Technical Details + + The relationship selector block's appearance is determined by the new relationship block that defines it. + + It has between 3 and 10 internal connectors for objects and values. If a connector is for a data type, it will only + accept values of that type and variables. If a connector is for a category, it will accept objects and variables. + + ## Tips + diff --git a/blawx/fixtures/docs/components/web-api.yaml b/blawx/fixtures/docs/components/web-api.yaml index 400c562a..84f850d1 100644 --- a/blawx/fixtures/docs/components/web-api.yaml +++ b/blawx/fixtures/docs/components/web-api.yaml @@ -60,10 +60,20 @@ "AttributeNLG" is a list of dictionaries, each of which has the keys "Attribute", "Order", "Prefix", "Infix" and "Postfix", describing the details provided in an attribute declaration block. Order will be either "vo" or "ov", indicating the order in which the object and the value appear in the natural language expression. + "Relationships" is a list of dictionaries, each of which has the key "Relationship", and between 3 and 10 keys "ParameterN" where N is replaced with the number of the parameter. The "Relationship" + is the name of the relationship. Inside each "ParameterN" key is the data type or category for that parameter in the relationship. The available types are the same as for attributes. + + "RelationshipNLG" is a list of dictionaries, each of which has the keys "Relationship", "Postfix", and between 3 and 10 "PrefixN" keys where N is replaced with the number of the parameter. The + relationship key is the name of the relationship, the PrefixN keys hold text that should appear before each of the parameters in the relationship, and the Postfix key holds text that should appear + after all parameters. + "Objects" is a list of dictionaries, each with the keys "Category" and "Object", describing the category and the name of the object in that category. "Values" is a list of dictionaries, each with the keys "Object", "Attribute", and "Value", describing a known value for that object and attribute. + "Relations" is a list of dictionaries, each with the keys "Relationship", and a set of 3 to 10 keys named "ParameterN" where N is replaced with the number of the parameter, describing a known + statement for that relationship. + The ontology endpoint is intended to be used at the start of an interaction between Blawx and another application, to provide the other application with information about what data structure is used in the encoding, and to provide hints about how to collect items into that data structure. @@ -82,9 +92,10 @@ * A 'from_ontology' key, the value of which is a `true` or `false` value. This is used to note which facts were already present in the code and were not provided by the user. Data provided by a user application should always set the 'from_ontology' value to `false`. * A 'type' key, the values of which can be the strings 'true','false', or 'unknown'. - * Either a 'category' or 'attribute' key, where the value is the name of the category or attribute about which a statement is being made. - * An 'object' key, the value of which is either the name of an object as a string, or a variable definition (described below). + * Either a 'category', 'attribute', or 'relationship' key, where the value is the name of the category or attribute or relationship about which a statement is being made. + * For categories and attributes only, an 'object' key, the value of which is either the name of an object as a string, or a variable definition (described below). * In the case of non-boolean attributes, a 'value' key, the value of which is the particular value being provided, or a variable definition (described below). + * For relationships, a set of between 3 and 10 "parameterN" keys where N is replaced with the parameter number, setting out the value or variable definition for each. Dates, datetimes, times, and durations are provided as strings in ISO8601 format. Numbers and booleans are provided in the standard JSON format. ``` @@ -112,7 +123,13 @@ 'attribute': 'duration', 'object': 'bob', 'value': 'P1Y5MT5H30S' - } + }, + { 'from_ontology': flase, + 'type': 'true', + 'relationship': 'trio', + 'parameter1': 'bob', + 'parameter2': 'jane', + 'parameter3': 'terry'} ] } ``` @@ -146,10 +163,10 @@ ] } ``` - + Variable names are not case sensitive. The variable "one" and "One" will be treated as though they are identical. + Additional examples can be obtained by using the Scenario Editor to run a test, and then looking at the "Devel" tab, which will show the JSON package that was delivered to the interview endpoint, and the response. - The output from the interview endpoint is a JSON dictionary with keys "Answers", "Relevant Statements", and "Transcript". diff --git a/blawx/fixtures/docs/features/categories.yaml b/blawx/fixtures/docs/features/categories.yaml index e15310af..4da8ce4d 100644 --- a/blawx/fixtures/docs/features/categories.yaml +++ b/blawx/fixtures/docs/features/categories.yaml @@ -1,15 +1,13 @@ - model: blawx.docpage pk: features/categories fields: - title: Categories, Objects, and Attributes + title: Categories, Attributes, Relationships content: | - # Categories, Objects, and Attributes + # Categories, Attributes, and Relationships - Categories, Objects, and - Attributes are how Blawx organizes what it knows about the world. + Categories, Attributes, and Relationships are how Blawx organizes what it knows about the world. - A Category - is a type of object. For example, "Car." + A Category is a type of object. For example, "Car." A Category has Attributes, which are names for things that you can know about things in that Category. @@ -26,9 +24,9 @@ The information that you put into an object's attribute has to be of the correct type. You can't put a number - if the attribute is supposed to hold a true or false value, and vice-versa. + if the attribute is supposed to hold a date value, and vice-versa. - An easy way + An easy way to think of a Category is as a description of a blank form. The form might have a name, like “Application for a Permit”. That is like the Category name. A form will also have fields that can be filled in, like “Applicant’s Name". Those are @@ -40,11 +38,13 @@ of an object. Some fields on the form are for checkmarks, others numbers, and others dates. Those are like the types of the category attributes. - An - attribute can hold either a basic data type, or objects in a category. + A Relationship is a thing that is true about a combination of 3 or more objects and values. + For example, you might want to record information about where cars placed in races, and you + could create a relationship between a car (a category), a race (another category), and a number indicating the finishing position. - The - basic data types are numbers, true or false values, dates, and durations. + An attribute or a relationship can hold either a basic data type, or objects in a category. + + The basic data types are numbers, true or false values, dates, times, datetimes, durations, and lists. Not only can you use your Categories as a type, but you can use your category @@ -242,4 +242,18 @@ and the way that you say it is false is by surrounding it with a "it is false that" negation block. So when you create a "True / False" attribute, it has only an "object" field, and you only need to customize the text - that appears before and after the name of the object. \ No newline at end of file + that appears before and after the name of the object. + + ## Relationships + + You can create a relationship by using the new relationship block. You need to give it a name, which + must be lower case and not have spaces. You also need to give it a number of objects or values that will + be related to one another. Note that if what you are looking for is a relationship between 2 objects, + you should use an Attribute instead. + + ![New Relationship Block](/static/blawx/docs/images/blocks/new_relationship.png) + + Once you have chosen the name and the number of objects or values, you will be able to choose a type for + each of the elements, choosing between the available data types and the known categories. You can also + provide the text that should appear before, between, and after all of the elements. This text will be used + to build the relationship selector block, and will be used in explanations. \ No newline at end of file diff --git a/blawx/reasoner.py b/blawx/reasoner.py index 93190df4..419f522a 100644 --- a/blawx/reasoner.py +++ b/blawx/reasoner.py @@ -71,162 +71,239 @@ def has_permission(self, request, view): # ] # } -def newer_json_2_scasp(payload,ruledoc,testname): - output = "" +def isVariable(param): + if type(param) is dict and 'variable' in param: + return True + else: + return False + +# Note that this makes the variables in the JSON input case-insensitive. +def convertVariables(param): + if type(param) is dict and 'variable' in param: + return param['variable'].upper() + else: + return param - - # Grab the ontology for the current test. +# TODO This isn't dealing with variables properly, because they appear as dictionaries, now. +# We need to grab the actual variable names used, because they can be significantly more than X and Y, now. +# TODO This version also doesn't have even draft code for building abducibles, yet. +def even_newer_json_2_scasp(payload,ruledoc,testname): + output = "" ontology = get_ontology_internal(ruledoc,testname) + # Basically, we need to know what the predicate is, what the parameters are, whether the parameters have category types, and if they are variables. + # So get the predicate, look up the typing, modify for negation if required, and generate the fact, testing for categories if required. + + # Statement (:- Conditions) . + # Statement = [negation]predicate(params) + # The params are the object, the object and the value, or the params in order, depending. + # If any of them is typed to a category, and is a variable, that category and that variable are added to the conditions. - # For doing abducibility, we need a list of all the known objects provided - # by the ontology and the user in each category. - # known_objects = {} - # for c in ontology['Categories']: - # known_objects[c] = [] - # for o in ontology['Objects']: - # known_objects[o['Category']].append(o['Object']) - # for fact in payload['facts']: - # if 'category' in fact and not fact['from_ontology'] and type(fact['object']) is not dict and fact['type'] == "true": # Last excludes variables, and false - # known_objects[fact['category']].append(fact['object']) - - # print("Known Objects Gathered:") - # print(known_objects) - # Go through the statements and convert them into s(CASP) for fact in payload['facts']: if 'from_ontology' in fact and not fact['from_ontology']: + negation = "-" if fact['type'] == "false" else "" if 'category' in fact: - basic_predicate = fact['category'] - is_attribute = False + predicate = fact['category'] + parameters = [fact['object']] + categories = [predicate] elif 'attribute' in fact: - is_attribute = True - basic_predicate = fact['attribute'] - attribute_type = "object" - for att in ontology['Attributes']: - if basic_predicate == att['Attribute']: - attribute_type = att['Type'] - object_type = att['Category'] - break - truth_value = fact['type'] - statement_object = fact['object'] - if type(statement_object) is dict: - statement_object = "X" - if truth_value == "false": - predicate = "-" + basic_predicate - else: - predicate = basic_predicate - if truth_value != "unknown": + predicate = fact['attribute'] if 'value' in fact: - statement_value = fact['value'] - if type(statement_value) is dict: - statement_value = "Y" - # attribute_type = "object" - # for att in ontology['Attributes']: - # if basic_predicate == att['Attribute']: - # attribute_type = att['Type'] - # object_type = att['Category'] - # break - output += predicate + "(" + statement_object + "," + format_statement_value(statement_value,attribute_type) + ")" - if statement_object == "X" or statement_value == "Y": - output += " :- " - if statement_object == "X": - output += object_type + "(X)" - if statement_object == "X" and statement_value == "Y": - output += ", " - if statement_value == "Y": - output += attribute_type + "(Y)" - output += ".\n" + parameters = [fact['object'],fact['value']] + for att in ontology['Attributes']: + if predicate == att['Attribute']: + object_category = att['Category'] + if att['Type'] in ontology['Categories']: + value_category = att['Type'] + else: + value_category = "none" + break + categories = [object_category,value_category] else: - output += predicate + "(" + statement_object + ")" - if statement_object == "X" and is_attribute: - output += ":- " + object_type + "(X)" - output += ".\n" - for fact in payload['facts']: - if 'from_ontology' in fact and not fact['from_ontology']: - if 'category' in fact: - basic_predicate = fact['category'] - is_attribute = False - elif 'attribute' in fact: - basic_predicate = fact['attribute'] - attribute_type = "object" - for att in ontology['Attributes']: - if basic_predicate == att['Attribute']: - attribute_type = att['Type'] - object_type = att['Category'] + parameters = [fact['object']] + for att in ontology['Attributes']: + if predicate == att['Attribute']: + object_category = att['Category'] break - is_attribute = True - truth_value = fact['type'] - if fact['type'] == "unknown": - # This statement is an abducibility: - if 'category' in fact: - # If it is a category, we need -category(X) :- not category(X), x \= list of known objects in the category, and the opposite. - # We need to check to see if the variable is unground, and include the exclusions only if it is unground. - if type(fact['object']) is dict: - object_display = "X" - else: - object_display = fact['object'] - output += basic_predicate + "(" + object_display + ") :- not -" + basic_predicate + "(" + object_display + ")" - if object_display == "X": - output += object_type + "(X)" - output += ".\n" - output += "-" + basic_predicate + "(" + object_display + ") :- not " + basic_predicate + "(" + object_display + ")" - if object_display == "X": - output += object_type + "(X)" - output += ".\n" - if 'attribute' in fact: - # If it is an attribute, we need attribute(X,Y) :- not -attribute(X,Y), X \= list of known objects in the category, Y \= list of known objects in target category, and the opposite. - # Get the object type for the attribute, and get the value type if it exists. - # for att in ontology['Attributes']: - # if att['Attribute'] == fact['attribute']: - # object_type = att['Category'] - # value_type = att['Type'] - # We also need to know if the value_type is a category - value_is_object = attribute_type in ontology['Categories'] - if type(fact['object']) is dict: - object_display = "X" - else: - object_display = fact['object'] - if 'value' in fact and type(fact['value']) is dict: - value_display = "Y" - elif 'value' in fact: - value_display = fact['value'] - # This will cause it to use the same variable name twice if both the subject and object are unground and they use the same variable name. - if object_display == "X" and value_display == "Y": - if fact['object']['variable'] == fact['value']['variable']: - value_display == "X" - if 'value' in fact: # This is the binary predicate type - output += basic_predicate + "(" + object_display + "," + value_display + ") :- " - if object_display == "X": - output += object_type + "(X)" - if object_display == "X" and (value_display == "X" or value_display == "Y"): - output += ", " - if value_display == "X" or value_display == "Y": - output += attribute_type + "(" + value_display + ")" - if object_display == "X" or (value_display == "X" or value_display == "Y"): - output += ", " - output += " not -" + basic_predicate + "(" + object_display + "," + value_display + ").\n" - output += "-" + basic_predicate + "(" + object_display + "," + value_display + ") :- " - if object_display == "X": - output += object_type + "(X)" - if object_display == "X" and (value_display == "X" or value_display == "Y"): - output += ", " - if value_display == "X" or value_display == "Y": - output += attribute_type + "(" + value_display + ")" - if object_display == "X" or (value_display == "X" or value_display == "Y"): - output += ", " - output += " not " + basic_predicate + "(" + object_display + "," + value_display + ").\n" - else: # This is the unary predicate type. - output += basic_predicate + "(" + object_display + ") :- " - if object_display == "X": - output += object_type + "(X), " - output += "not -" + basic_predicate + "(" + object_display + ").\n" - output += "-" + basic_predicate + "(" + object_display + ") :- " - if object_display == "X": - output += object_type + "(X), " - output += "not " + basic_predicate + "(" + object_display + ").\n" - # print("Generated Facts") - # print(output) + categories = [object_category] + elif 'relationship' in fact: + predicate = fact['relationship'] + arity = len(fact)-3 # Subtract "from ontology" "type" and "relationship" + parameters = [] + p = 1 + while p <= arity: + parameters.append(fact['parameter'+str(p)]) + p += 1 + categories = [] + for rel in ontology['Relationships']: + if predicate == rel['Relationship']: + p = 1 + while p <= arity: + if rel['Parameter'+str(p)] in ontology['Categories']: + categories.append(rel['Parameter'+str(p)]) + else: + categories.append('none') + p += 1 + break + variables = list(map(isVariable, parameters)) + parameters = list(map(convertVariables, parameters)) + if fact['type'] != "unknown": # This is a true or false statement + conditions = [] + for index, param in enumerate(parameters): + if variables[index] and categories[index] != "none": + conditions.append(categories[index] + "(" + param + ")") + statement = negation + predicate + "(" + ','.join(parameters) + ")" + output += statement + (" :- " if len(conditions) else "") + ','.join(conditions) + ".\n" + else: # This is an unknown statement + # Something should be added to the conditions if the parameter is a variable, and the type is a category. If so, the conditions should exclude all + # the known elements of that category. + conditions = [] + for index, param in enumerate(parameters): + if variables[index] and categories[index] != "none": + for obj in ontology['Objects']: + if obj['Category'] == categories[index]: + conditions.append(param + " \= " + obj['Object']) + positive_statement = predicate + "(" + ",".join(parameters) + ") :- not -" + predicate + "(" + ",".join(parameters) + ")" + ("," if len(conditions) else "") + ",".join(conditions) + ".\n" + negative_statement = "-" + predicate + "(" + ",".join(parameters) + ") :- not " + predicate + "(" + ",".join(parameters) + ")" + ("," if len(conditions) else "") + ",".join(conditions) + ".\n" + output += positive_statement + negative_statement return output + +# def newer_json_2_scasp(payload,ruledoc,testname): +# output = "" + + +# # Grab the ontology for the current test. +# ontology = get_ontology_internal(ruledoc,testname) + + +# # Go through the statements and convert them into s(CASP) +# for fact in payload['facts']: +# if 'from_ontology' in fact and not fact['from_ontology']: +# if 'category' in fact: +# basic_predicate = fact['category'] +# is_attribute = False +# elif 'attribute' in fact: +# is_attribute = True +# basic_predicate = fact['attribute'] +# attribute_type = "object" +# for att in ontology['Attributes']: +# if basic_predicate == att['Attribute']: +# attribute_type = att['Type'] +# object_type = att['Category'] +# break +# truth_value = fact['type'] +# statement_object = fact['object'] +# if type(statement_object) is dict: +# statement_object = "X" +# if truth_value == "false": +# predicate = "-" + basic_predicate +# else: +# predicate = basic_predicate +# if truth_value != "unknown": +# if 'value' in fact: +# statement_value = fact['value'] +# if type(statement_value) is dict: +# statement_value = "Y" +# output += predicate + "(" + statement_object + "," + format_statement_value(statement_value,attribute_type) + ")" +# if statement_object == "X" or statement_value == "Y": +# output += " :- " +# if statement_object == "X": +# output += object_type + "(X)" +# if statement_object == "X" and statement_value == "Y": +# output += ", " +# if statement_value == "Y": +# output += attribute_type + "(Y)" +# output += ".\n" +# else: +# output += predicate + "(" + statement_object + ")" +# if statement_object == "X" and is_attribute: +# output += ":- " + object_type + "(X)" +# output += ".\n" +# for fact in payload['facts']: +# if 'from_ontology' in fact and not fact['from_ontology']: +# if 'category' in fact: +# basic_predicate = fact['category'] +# is_attribute = False +# elif 'attribute' in fact: +# basic_predicate = fact['attribute'] +# attribute_type = "object" +# for att in ontology['Attributes']: +# if basic_predicate == att['Attribute']: +# attribute_type = att['Type'] +# object_type = att['Category'] +# break +# is_attribute = True +# truth_value = fact['type'] +# if fact['type'] == "unknown": +# # This statement is an abducibility: +# if 'category' in fact: +# # If it is a category, we need -category(X) :- not category(X), x \= list of known objects in the category, and the opposite. +# # We need to check to see if the variable is unground, and include the exclusions only if it is unground. +# if type(fact['object']) is dict: +# object_display = "X" +# else: +# object_display = fact['object'] +# output += basic_predicate + "(" + object_display + ") :- not -" + basic_predicate + "(" + object_display + ")" +# if object_display == "X": +# output += object_type + "(X)" +# output += ".\n" +# output += "-" + basic_predicate + "(" + object_display + ") :- not " + basic_predicate + "(" + object_display + ")" +# if object_display == "X": +# output += object_type + "(X)" +# output += ".\n" +# if 'attribute' in fact: +# # If it is an attribute, we need attribute(X,Y) :- not -attribute(X,Y), X \= list of known objects in the category, Y \= list of known objects in target category, and the opposite. +# # Get the object type for the attribute, and get the value type if it exists. +# # for att in ontology['Attributes']: +# # if att['Attribute'] == fact['attribute']: +# # object_type = att['Category'] +# # value_type = att['Type'] +# # We also need to know if the value_type is a category +# value_is_object = attribute_type in ontology['Categories'] +# if type(fact['object']) is dict: +# object_display = "X" +# else: +# object_display = fact['object'] +# if 'value' in fact and type(fact['value']) is dict: +# value_display = "Y" +# elif 'value' in fact: +# value_display = fact['value'] +# # This will cause it to use the same variable name twice if both the subject and object are unground and they use the same variable name. +# if object_display == "X" and value_display == "Y": +# if fact['object']['variable'] == fact['value']['variable']: +# value_display == "X" +# if 'value' in fact: # This is the binary predicate type +# output += basic_predicate + "(" + object_display + "," + value_display + ") :- " +# if object_display == "X": +# output += object_type + "(X)" +# if object_display == "X" and (value_display == "X" or value_display == "Y"): +# output += ", " +# if value_display == "X" or value_display == "Y": +# output += attribute_type + "(" + value_display + ")" +# if object_display == "X" or (value_display == "X" or value_display == "Y"): +# output += ", " +# output += " not -" + basic_predicate + "(" + object_display + "," + value_display + ").\n" +# output += "-" + basic_predicate + "(" + object_display + "," + value_display + ") :- " +# if object_display == "X": +# output += object_type + "(X)" +# if object_display == "X" and (value_display == "X" or value_display == "Y"): +# output += ", " +# if value_display == "X" or value_display == "Y": +# output += attribute_type + "(" + value_display + ")" +# if object_display == "X" or (value_display == "X" or value_display == "Y"): +# output += ", " +# output += " not " + basic_predicate + "(" + object_display + "," + value_display + ").\n" +# else: # This is the unary predicate type. +# output += basic_predicate + "(" + object_display + ") :- " +# if object_display == "X": +# output += object_type + "(X), " +# output += "not -" + basic_predicate + "(" + object_display + ").\n" +# output += "-" + basic_predicate + "(" + object_display + ") :- " +# if object_display == "X": +# output += object_type + "(X), " +# output += "not " + basic_predicate + "(" + object_display + ").\n" +# return output + def format_statement_value(value,attribute_type): iso8601_date_re = r"^(\d{4})-(\d{2})-(\d{2})$" time_re = r"^(\d{2}):(\d{2})$" @@ -399,7 +476,7 @@ def run_test(request,ruledoc,test_name): if request.user.has_perm('blawx.run',test): translated_facts = "" if request.data: - translated_facts = newer_json_2_scasp(request.data,ruledoc,test_name) + translated_facts = even_newer_json_2_scasp(request.data,ruledoc,test_name) # print("Facts Generated for Run Request:\n") # print(translated_facts) wss = Workspace.objects.filter(ruledoc=RuleDoc.objects.get(pk=ruledoc)) @@ -662,6 +739,180 @@ def get_ontology_internal(ruledoc,test_name): for anlga in att_nlg_query_answers: attribute_nlg.append({"Attribute": a['Attribute'], "Order": anlga['Variables']['Order'], "Prefix": anlga['Variables']['Prefix'], "Infix": anlga['Variables']['Infix'], "Postfix": anlga['Variables']['Postfix']}) + relationship_answers = [] + query3_answers = [] + try: + query3_answer = swipl_thread.query("blawxrun(blawx_relationship(Relationship,Param1,Param2,Param3),Human).") + query3_answers = generate_answers(query3_answer) + for att in query3_answers: + # This excludes declarations that make variables into attribute types. + # TODO: I don't know if this is useful, here. It's checking to see if there are any variables being returned as the value type, category, or attribute. But + # I'm having difficulty figuring out why that was ever a concern. There is no way to generate a blawx_relationship statement with variables in it. + #if not re.search(r"^[A-Z_]\w*",att['Variables']['ValueType']) and not re.search(r"^[A-Z_]\w*",att['Variables']['Category']) and not re.search(r"^[A-Z_]\w*",att['Variables']['Attribute']): + relationship_answers.append({"Relationship": att['Variables']['Relationship'], "Parameter1": att['Variables']['Param1'], "Parameter2": att['Variables']['Param2'], "Parameter3": att['Variables']['Param3']}) + transcript.write(str(query3_answer) + '\n') + except PrologError as err: + if err.prolog().startswith('existence_error'): + pass + + query4_answers = [] + try: + query4_answer = swipl_thread.query("blawxrun(blawx_relationship(Relationship,Param1,Param2,Param3,Param4),Human).") + query4_answers = generate_answers(query4_answer) + for att in query4_answers: + # This excludes declarations that make variables into attribute types. + # TODO: I don't know if this is useful, here. It's checking to see if there are any variables being returned as the value type, category, or attribute. But + # I'm having difficulty figuring out why that was ever a concern. There is no way to generate a blawx_relationship statement with variables in it. + #if not re.search(r"^[A-Z_]\w*",att['Variables']['ValueType']) and not re.search(r"^[A-Z_]\w*",att['Variables']['Category']) and not re.search(r"^[A-Z_]\w*",att['Variables']['Attribute']): + relationship_answers.append({"Relationship": att['Variables']['Relationship'], "Parameter1": att['Variables']['Param1'], "Parameter2": att['Variables']['Param2'], "Parameter3": att['Variables']['Param3'], "Parameter4": att['Variables']['Param4']}) + transcript.write(str(query4_answer) + '\n') + except PrologError as err: + if err.prolog().startswith('existence_error'): + pass + + + query5_answers = [] + try: + query5_answer = swipl_thread.query("blawxrun(blawx_relationship(Relationship,Param1,Param2,Param3,Param4,Param5),Human).") + query5_answers = generate_answers(query5_answer) + for att in query5_answers: + # This excludes declarations that make variables into attribute types. + # TODO: I don't know if this is useful, here. It's checking to see if there are any variables being returned as the value type, category, or attribute. But + # I'm having difficulty figuring out why that was ever a concern. There is no way to generate a blawx_relationship statement with variables in it. + #if not re.search(r"^[A-Z_]\w*",att['Variables']['ValueType']) and not re.search(r"^[A-Z_]\w*",att['Variables']['Category']) and not re.search(r"^[A-Z_]\w*",att['Variables']['Attribute']): + relationship_answers.append({"Relationship": att['Variables']['Relationship'], "Parameter1": att['Variables']['Param1'], "Parameter2": att['Variables']['Param2'], "Parameter3": att['Variables']['Param3'], "Parameter4": att['Variables']['Param4'], "Parameter5": att['Variables']['Param5']}) + transcript.write(str(query5_answer) + '\n') + except PrologError as err: + if err.prolog().startswith('existence_error'): + pass + + + query6_answers = [] + try: + query6_answer = swipl_thread.query("blawxrun(blawx_relationship(Relationship,Param1,Param2,Param3,Param4,Param5,Param6),Human).") + query6_answers = generate_answers(query6_answer) + for att in query6_answers: + # This excludes declarations that make variables into attribute types. + # TODO: I don't know if this is useful, here. It's checking to see if there are any variables being returned as the value type, category, or attribute. But + # I'm having difficulty figuring out why that was ever a concern. There is no way to generate a blawx_relationship statement with variables in it. + #if not re.search(r"^[A-Z_]\w*",att['Variables']['ValueType']) and not re.search(r"^[A-Z_]\w*",att['Variables']['Category']) and not re.search(r"^[A-Z_]\w*",att['Variables']['Attribute']): + relationship_answers.append({"Relationship": att['Variables']['Relationship'], "Parameter1": att['Variables']['Param1'], "Parameter2": att['Variables']['Param2'], "Parameter3": att['Variables']['Param3'], "Parameter4": att['Variables']['Param4'], "Parameter5": att['Variables']['Param5'], "Parameter6": att['Variables']['Param6']}) + transcript.write(str(query6_answer) + '\n') + except PrologError as err: + if err.prolog().startswith('existence_error'): + pass + + + query7_answers = [] + try: + query7_answer = swipl_thread.query("blawxrun(blawx_relationship(Relationship,Param1,Param2,Param3,Param4,Param5,Param6,Param7),Human).") + query7_answers = generate_answers(query7_answer) + for att in query7_answers: + # This excludes declarations that make variables into attribute types. + # TODO: I don't know if this is useful, here. It's checking to see if there are any variables being returned as the value type, category, or attribute. But + # I'm having difficulty figuring out why that was ever a concern. There is no way to generate a blawx_relationship statement with variables in it. + #if not re.search(r"^[A-Z_]\w*",att['Variables']['ValueType']) and not re.search(r"^[A-Z_]\w*",att['Variables']['Category']) and not re.search(r"^[A-Z_]\w*",att['Variables']['Attribute']): + relationship_answers.append({"Relationship": att['Variables']['Relationship'], "Parameter1": att['Variables']['Param1'], "Parameter2": att['Variables']['Param2'], "Parameter3": att['Variables']['Param3'], "Parameter4": att['Variables']['Param4'], "Parameter5": att['Variables']['Param5'], "Parameter6": att['Variables']['Param6'], "Parameter7": att['Variables']['Param7']}) + transcript.write(str(query7_answer) + '\n') + except PrologError as err: + if err.prolog().startswith('existence_error'): + pass + + + query8_answers = [] + try: + query8_answer = swipl_thread.query("blawxrun(blawx_relationship(Relationship,Param1,Param2,Param3,Param4,Param5,Param6,Param7,Param8),Human).") + query8_answers = generate_answers(query8_answer) + for att in query8_answers: + # This excludes declarations that make variables into attribute types. + # TODO: I don't know if this is useful, here. It's checking to see if there are any variables being returned as the value type, category, or attribute. But + # I'm having difficulty figuring out why that was ever a concern. There is no way to generate a blawx_relationship statement with variables in it. + #if not re.search(r"^[A-Z_]\w*",att['Variables']['ValueType']) and not re.search(r"^[A-Z_]\w*",att['Variables']['Category']) and not re.search(r"^[A-Z_]\w*",att['Variables']['Attribute']): + relationship_answers.append({"Relationship": att['Variables']['Relationship'], "Parameter1": att['Variables']['Param1'], "Parameter2": att['Variables']['Param2'], "Parameter3": att['Variables']['Param3'], "Parameter4": att['Variables']['Param4'], "Parameter5": att['Variables']['Param5'], "Parameter6": att['Variables']['Param6'], "Parameter7": att['Variables']['Param7'], "Parameter8": att['Variables']['Param8']}) + transcript.write(str(query8_answer) + '\n') + except PrologError as err: + if err.prolog().startswith('existence_error'): + pass + + + query9_answers = [] + try: + query9_answer = swipl_thread.query("blawxrun(blawx_relationship(Relationship,Param1,Param2,Param3,Param4,Param5,Param6,Param7,Param8,Param9),Human).") + query9_answers = generate_answers(query9_answer) + for att in query9_answers: + # This excludes declarations that make variables into attribute types. + # TODO: I don't know if this is useful, here. It's checking to see if there are any variables being returned as the value type, category, or attribute. But + # I'm having difficulty figuring out why that was ever a concern. There is no way to generate a blawx_relationship statement with variables in it. + #if not re.search(r"^[A-Z_]\w*",att['Variables']['ValueType']) and not re.search(r"^[A-Z_]\w*",att['Variables']['Category']) and not re.search(r"^[A-Z_]\w*",att['Variables']['Attribute']): + relationship_answers.append({"Relationship": att['Variables']['Relationship'], "Parameter1": att['Variables']['Param1'], "Parameter2": att['Variables']['Param2'], "Parameter3": att['Variables']['Param3'], "Parameter4": att['Variables']['Param4'], "Parameter5": att['Variables']['Param5'], "Parameter6": att['Variables']['Param6'], "Parameter7": att['Variables']['Param7'], "Parameter8": att['Variables']['Param8'], "Parameter9": att['Variables']['Param9']}) + transcript.write(str(query9_answer) + '\n') + except PrologError as err: + if err.prolog().startswith('existence_error'): + pass + + query10_answers = [] + try: + query10_answer = swipl_thread.query("blawxrun(blawx_relationship(Relationship,Param1,Param2,Param3,Param4,Param5,Param6,Param7,Param8,Param9,Param10),Human).") + query10_answers = generate_answers(query10_answer) + for att in query10_answers: + # This excludes declarations that make variables into attribute types. + # TODO: I don't know if this is useful, here. It's checking to see if there are any variables being returned as the value type, category, or attribute. But + # I'm having difficulty figuring out why that was ever a concern. There is no way to generate a blawx_relationship statement with variables in it. + #if not re.search(r"^[A-Z_]\w*",att['Variables']['ValueType']) and not re.search(r"^[A-Z_]\w*",att['Variables']['Category']) and not re.search(r"^[A-Z_]\w*",att['Variables']['Attribute']): + relationship_answers.append({"Relationship": att['Variables']['Relationship'], "Parameter1": att['Variables']['Param1'], "Parameter2": att['Variables']['Param2'], "Parameter3": att['Variables']['Param3'], "Parameter4": att['Variables']['Param4'], "Parameter5": att['Variables']['Param5'], "Parameter6": att['Variables']['Param6'], "Parameter7": att['Variables']['Param7'], "Parameter8": att['Variables']['Param8'], "Parameter9": att['Variables']['Param9'], "Parameter10": att['Variables']['Param10']}) + transcript.write(str(query10_answer) + '\n') + except PrologError as err: + if err.prolog().startswith('existence_error'): + pass + + relationship_nlg = [] + for a in relationship_answers: + try: + query = "blawxrun(blawx_relationship_nlg(" + a['Relationship'] + "," + parameters = len(a)-1 + param = 1 + while param <= parameters: + query += 'Prefix'+str(param) + "," + param += 1 + query += "Postfix),Human)." + rel_nlg_query_response = swipl_thread.query(query) + rel_nlg_answers = generate_answers(rel_nlg_query_response) + for relnlg in rel_nlg_answers: + new_nlg = {"Relationship": a['Relationship'], "Postfix": relnlg['Variables']['Postfix']} + param_count = 1 + while param_count <= parameters: + new_nlg['Prefix'+str(param_count)] = relnlg['Variables']['Prefix'+str(param_count)] + param_count += 1 + relationship_nlg.append(new_nlg) + except PrologError as err: + if err.prolog().startswith('existence_error'): + continue + + rel_facts = [] + for a in relationship_answers: + try: + query = "blawxrun(" + a['Relationship'] + "(" + parameters = len(a)-1 + param = 1 + while param <= parameters: + query += 'Parameter'+str(param) + if param < parameters: + query += "," + param += 1 + query += "),Human)." + rel_fact_query_response = swipl_thread.query(query) + rel_fact_answers = generate_answers(rel_fact_query_response) + for relfact in rel_fact_answers: + new_fact = {"Relationship": a['Relationship']} + param_count = 1 + while param_count <= parameters: + new_fact['Parameter'+str(param_count)] = relfact['Variables']['Parameter'+str(param_count)] + param_count += 1 + rel_facts.append(new_fact) + except PrologError as err: + if err.prolog().startswith('existence_error'): + continue + transcript.write(str(query1_answer) + '\n') object_query_answers = [] for cat in query1_answers: @@ -753,7 +1004,7 @@ def get_ontology_internal(ruledoc,test_name): except PrologLaunchError as err: return { "error": "Blawx could not load the reasoner." } # Return the results as JSON - return { "Categories": category_answers, "CategoryNLG": category_nlg, "Attributes": attribute_answers, "AttributeNLG": attribute_nlg, "Objects": object_query_answers, "Values": value_query_answers, "Transcript": transcript_output } + return { "Categories": category_answers, "CategoryNLG": category_nlg, "Attributes": attribute_answers, "AttributeNLG": attribute_nlg, "Relationships": relationship_answers, "RelationshipNLG": relationship_nlg, "Objects": object_query_answers, "Values": value_query_answers, "Relations": rel_facts, "Transcript": transcript_output } @api_view(['GET']) @authentication_classes([SessionAuthentication]) @@ -914,7 +1165,7 @@ def interview(request,ruledoc,test_name): # Effectively, we're going to start over. translated_facts = "" if request.data: - translated_facts = newer_json_2_scasp(request.data, ruledoc, test_name) #Generate answers INCLUDING assumptions in the submitted data + translated_facts = even_newer_json_2_scasp(request.data, ruledoc, test_name) #Generate answers INCLUDING assumptions in the submitted data wss = Workspace.objects.filter(ruledoc=RuleDoc.objects.get(pk=ruledoc)) test = BlawxTest.objects.get(ruledoc=RuleDoc.objects.get(pk=ruledoc),test_name=test_name) @@ -1104,7 +1355,7 @@ def simplify_term(term): simplified = {} simplified['functor'] = term['functor'] simplified['args'] = [] - replacements = ['X','Y'] # we don't use more than two-element terms + replacements = ['Q','R','S','T','U','V','W','X','Y','Z'] # We have up to 10-ary terms, now. r = 0 for a in term['args']: if type(a) == dict: # If the argument is a term, simplify it, too. Used to deal with negations, mostly. diff --git a/blawx/settings.py b/blawx/settings.py index 3e291e1f..0dfc2e6a 100644 --- a/blawx/settings.py +++ b/blawx/settings.py @@ -13,7 +13,7 @@ from pathlib import Path # For adding a version identifier -BLAWX_VERSION = "v1.6.0-alpha" +BLAWX_VERSION = "v1.6.1-alpha" # Build paths inside the project like this: BASE_DIR / 'subdir'. diff --git a/blawx/static/blawx/attributes.js b/blawx/static/blawx/attributes.js index 7778a4fe..a968ce62 100644 --- a/blawx/static/blawx/attributes.js +++ b/blawx/static/blawx/attributes.js @@ -1,5 +1,3 @@ - - function setAttributeType(event) { if (event.type == Blockly.Events.BLOCK_CREATE) { // console.log("Block was created."); diff --git a/blawx/static/blawx/blawx-blocks.js b/blawx/static/blawx/blawx-blocks.js index eb602099..c3aa488d 100644 --- a/blawx/static/blawx/blawx-blocks.js +++ b/blawx/static/blawx/blawx-blocks.js @@ -3967,6 +3967,1157 @@ scasp_blockset = [{ "colour": 330, "tooltip": "Generate a duration from a numerical timestamp value", "helpUrl": "/docs/blocks/duration_from_ts" +}, +{ + "type": "relationship_declaration", + "message0": "%1 is a relationship between %2 objects or values described as %3 %4 %5 %6 %7 %8 %9 %10", + "args0": [ + { + "type": "field_input", + "name": "relationship_name", + "text": "relationship_name" + }, + { + "type": "field_dropdown", + "name": "arity", + "options": [ + [ + "3", + "3" + ], + [ + "4", + "4" + ], + [ + "5", + "5" + ], + [ + "6", + "6" + ], + [ + "7", + "7" + ], + [ + "8", + "8" + ], + [ + "9", + "9" + ], + [ + "10", + "10" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "field_input", + "name": "prefix1", + "text": "" + }, + { + "type": "field_dropdown", + "name": "type1", + "options": [ + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ] + ] + }, + { + "type": "field_input", + "name": "prefix2", + "text": "" + }, + { + "type": "field_dropdown", + "name": "type2", + "options": [ + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ] + ] + }, + { + "type": "field_input", + "name": "prefix3", + "text": "" + }, + { + "type": "field_dropdown", + "name": "type3", + "options": [ + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ] + ] + }, + { + "type": "field_input", + "name": "postfix", + "text": "" + } + ], + "previousStatement": [ + "OUTER", + "STATEMENT" + ], + "nextStatement": "STATEMENT", + "colour": 30, + "tooltip": "Use to declare a relationship between 3 or more objects or values.", + "helpUrl": "/docs/blocks/new_relationship/" +}, +{ + "type": "relationship_selector", + "message0": "%1 %2 %3 %4 %5 %6 %7", + "args0": [ + { + "type": "field_label_serializable", + "name": "prefix1", + "text": "prefix1" + }, + { + "type": "input_value", + "name": "first_element" + }, + { + "type": "field_label_serializable", + "name": "prefix2", + "text": "prefix2" + }, + { + "type": "input_value", + "name": "second_element" + }, + { + "type": "field_label_serializable", + "name": "prefix3", + "text": "prefix3" + }, + { + "type": "input_value", + "name": "third_element" + }, + { + "type": "field_label_serializable", + "name": "postfix", + "text": "postfix" + } + ], + "inputsInline": true, + "previousStatement": [ + "OUTER", + "STATEMENT" + ], + "nextStatement": "STATEMENT", + "colour": 150, + "tooltip": "Use to set or check the value of a relationship.", + "helpUrl": "/docs/blocks/relationship_selector/" +}, +{ + "type": "relationship_ddeclaration", + "message0": "%1 is a relationship between %2 objects or values described as %3 %4 %5 %6 %7 %8 %9 %10", + "args0": [ + { + "type": "field_input", + "name": "relationship_name", + "text": "relationship_name" + }, + { + "type": "field_dropdown", + "name": "arity", + "options": [ + [ + "3", + "3" + ], + [ + "4", + "4" + ], + [ + "5", + "5" + ], + [ + "6", + "6" + ], + [ + "7", + "7" + ], + [ + "8", + "8" + ], + [ + "9", + "9" + ], + [ + "10", + "10" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "field_input", + "name": "prefix1", + "text": "" + }, + { + "type": "field_dropdown", + "name": "type1", + "options": [ + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ] + ] + }, + { + "type": "field_input", + "name": "prefix2", + "text": "" + }, + { + "type": "field_dropdown", + "name": "type2", + "options": [ + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ] + ] + }, + { + "type": "field_input", + "name": "prefix3", + "text": "" + }, + { + "type": "field_dropdown", + "name": "type3", + "options": [ + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ] + ] + }, + { + "type": "field_input", + "name": "postfix", + "text": "" + } + ], + "previousStatement": [ + "OUTER", + "STATEMENT" + ], + "nextStatement": "STATEMENT", + "colour": 30, + "tooltip": "Use to declare a relationship between 3 or more objects or values.", + "helpUrl": "/docs/blocks/new_relationship/" +}, +{ + "type": "relationship_selector3", + "message0": "%1 %2 %3 %4 %5 %6 %7", + "args0": [ + { + "type": "field_label_serializable", + "name": "prefix1", + "text": "prefix1" + }, + { + "type": "input_value", + "name": "parameter1", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix2", + "text": "prefix2" + }, + { + "type": "input_value", + "name": "parameter2", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix3", + "text": "prefix3" + }, + { + "type": "input_value", + "name": "parameter3", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "postfix", + "text": "postfix" + } + ], + "inputsInline": true, + "previousStatement": [ + "OUTER", + "STATEMENT" + ], + "nextStatement": "STATEMENT", + "colour": 195, + "tooltip": "Use to set or check the value of a relationship.", + "helpUrl": "/docs/blocks/relationship_selector/" +}, +{ + "type": "relationship_selector4", + "message0": "%1 %2 %3 %4 %5 %6 %7 %8 %9", + "args0": [ + { + "type": "field_label_serializable", + "name": "prefix1", + "text": "prefix1" + }, + { + "type": "input_value", + "name": "parameter1", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix2", + "text": "prefix2" + }, + { + "type": "input_value", + "name": "parameter2", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix3", + "text": "prefix3" + }, + { + "type": "input_value", + "name": "parameter3", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix4", + "text": "prefix4" + }, + { + "type": "input_value", + "name": "parameter4", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "postfix", + "text": "postfix" + } + ], + "inputsInline": true, + "previousStatement": [ + "OUTER", + "STATEMENT" + ], + "nextStatement": "STATEMENT", + "colour": 195, + "tooltip": "Use to set or check the value of a relationship.", + "helpUrl": "/docs/blocks/relationship_selector/" +}, +{ + "type": "relationship_selector5", + "message0": "%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11", + "args0": [ + { + "type": "field_label_serializable", + "name": "prefix1", + "text": "prefix1" + }, + { + "type": "input_value", + "name": "parameter1", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix2", + "text": "prefix2" + }, + { + "type": "input_value", + "name": "parameter2", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix3", + "text": "prefix3" + }, + { + "type": "input_value", + "name": "parameter3", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix4", + "text": "prefix4" + }, + { + "type": "input_value", + "name": "parameter4", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix5", + "text": "prefix5" + }, + { + "type": "input_value", + "name": "parameter5", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "postfix", + "text": "postfix" + } + ], + "inputsInline": true, + "previousStatement": [ + "OUTER", + "STATEMENT" + ], + "nextStatement": "STATEMENT", + "colour": 195, + "tooltip": "Use to set or check the value of a relationship.", + "helpUrl": "/docs/blocks/relationship_selector/" +}, +{ + "type": "relationship_selector6", + "message0": "%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13", + "args0": [ + { + "type": "field_label_serializable", + "name": "prefix1", + "text": "prefix1" + }, + { + "type": "input_value", + "name": "parameter1", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix2", + "text": "prefix2" + }, + { + "type": "input_value", + "name": "parameter2", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix3", + "text": "prefix3" + }, + { + "type": "input_value", + "name": "parameter3", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix4", + "text": "prefix4" + }, + { + "type": "input_value", + "name": "parameter4", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix5", + "text": "prefix5" + }, + { + "type": "input_value", + "name": "parameter5", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix6", + "text": "prefix6" + }, + { + "type": "input_value", + "name": "parameter6", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "postfix", + "text": "postfix" + } + ], + "inputsInline": true, + "previousStatement": [ + "OUTER", + "STATEMENT" + ], + "nextStatement": "STATEMENT", + "colour": 195, + "tooltip": "Use to set or check the value of a relationship.", + "helpUrl": "/docs/blocks/relationship_selector/" +}, +{ + "type": "relationship_selector7", + "message0": "%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15", + "args0": [ + { + "type": "field_label_serializable", + "name": "prefix1", + "text": "prefix1" + }, + { + "type": "input_value", + "name": "parameter1", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix2", + "text": "prefix2" + }, + { + "type": "input_value", + "name": "parameter2", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix3", + "text": "prefix3" + }, + { + "type": "input_value", + "name": "parameter3", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix4", + "text": "prefix4" + }, + { + "type": "input_value", + "name": "parameter4", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix5", + "text": "prefix5" + }, + { + "type": "input_value", + "name": "parameter5", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix6", + "text": "prefix6" + }, + { + "type": "input_value", + "name": "parameter6", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix7", + "text": "prefix7" + }, + { + "type": "input_value", + "name": "parameter7", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "postfix", + "text": "postfix" + } + ], + "inputsInline": true, + "previousStatement": [ + "OUTER", + "STATEMENT" + ], + "nextStatement": "STATEMENT", + "colour": 195, + "tooltip": "Use to set or check the value of a relationship.", + "helpUrl": "/docs/blocks/relationship_selector/" +}, +{ + "type": "relationship_selector8", + "message0": "%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15 %16 %17", + "args0": [ + { + "type": "field_label_serializable", + "name": "prefix1", + "text": "prefix1" + }, + { + "type": "input_value", + "name": "parameter1", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix2", + "text": "prefix2" + }, + { + "type": "input_value", + "name": "parameter2", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix3", + "text": "prefix3" + }, + { + "type": "input_value", + "name": "parameter3", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix4", + "text": "prefix4" + }, + { + "type": "input_value", + "name": "parameter4", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix5", + "text": "prefix5" + }, + { + "type": "input_value", + "name": "parameter5", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix6", + "text": "prefix6" + }, + { + "type": "input_value", + "name": "parameter6", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix7", + "text": "prefix7" + }, + { + "type": "input_value", + "name": "parameter7", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix8", + "text": "prefix8" + }, + { + "type": "input_value", + "name": "parameter8", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "postfix", + "text": "postfix" + } + ], + "inputsInline": true, + "previousStatement": [ + "OUTER", + "STATEMENT" + ], + "nextStatement": "STATEMENT", + "colour": 195, + "tooltip": "Use to set or check the value of a relationship.", + "helpUrl": "/docs/blocks/relationship_selector/" +}, +{ + "type": "relationship_selector9", + "message0": "%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15 %16 %17 %18 %19", + "args0": [ + { + "type": "field_label_serializable", + "name": "prefix1", + "text": "prefix1" + }, + { + "type": "input_value", + "name": "parameter1", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix2", + "text": "prefix2" + }, + { + "type": "input_value", + "name": "parameter2", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix3", + "text": "prefix3" + }, + { + "type": "input_value", + "name": "parameter3", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix4", + "text": "prefix4" + }, + { + "type": "input_value", + "name": "parameter4", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix5", + "text": "prefix5" + }, + { + "type": "input_value", + "name": "parameter5", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix6", + "text": "prefix6" + }, + { + "type": "input_value", + "name": "parameter6", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix7", + "text": "prefix7" + }, + { + "type": "input_value", + "name": "parameter7", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix8", + "text": "prefix8" + }, + { + "type": "input_value", + "name": "parameter8", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix9", + "text": "prefix9" + }, + { + "type": "input_value", + "name": "parameter9", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "postfix", + "text": "postfix" + } + ], + "inputsInline": true, + "previousStatement": [ + "OUTER", + "STATEMENT" + ], + "nextStatement": "STATEMENT", + "colour": 195, + "tooltip": "Use to set or check the value of a relationship.", + "helpUrl": "/docs/blocks/relationship_selector/" +}, +{ + "type": "relationship_selector10", + "message0": "%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15 %16 %17 %18 %19 %20 %21", + "args0": [ + { + "type": "field_label_serializable", + "name": "prefix1", + "text": "prefix1" + }, + { + "type": "input_value", + "name": "parameter1", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix2", + "text": "prefix2" + }, + { + "type": "input_value", + "name": "parameter2", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix3", + "text": "prefix3" + }, + { + "type": "input_value", + "name": "parameter3", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix4", + "text": "prefix4" + }, + { + "type": "input_value", + "name": "parameter4", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix5", + "text": "prefix5" + }, + { + "type": "input_value", + "name": "parameter5", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix6", + "text": "prefix6" + }, + { + "type": "input_value", + "name": "parameter6", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix7", + "text": "prefix7" + }, + { + "type": "input_value", + "name": "parameter7", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix8", + "text": "prefix8" + }, + { + "type": "input_value", + "name": "parameter8", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix9", + "text": "prefix9" + }, + { + "type": "input_value", + "name": "parameter9", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix10", + "text": "prefix10" + }, + { + "type": "input_value", + "name": "parameter10", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "postfix", + "text": "postfix" + } + ], + "inputsInline": true, + "previousStatement": [ + "OUTER", + "STATEMENT" + ], + "nextStatement": "STATEMENT", + "colour": 195, + "tooltip": "Use to set or check the value of a relationship.", + "helpUrl": "/docs/blocks/relationship_selector/" }] // TODO: A bunch of these things below are redundant as the blocks are being removed. @@ -3975,6 +5126,9 @@ for (var i = 0; i < scasp_blockset.length; i++) { if (scasp_blockset[i].type == "attribute_selector") { scasp_blockset[i]['mutator'] = "attribute_selector_mutator" }; + if (scasp_blockset[i].type.startsWith('relationship_selector')) { + scasp_blockset[i]['mutator'] = "relationship_selector_mutator"; + }; if (scasp_blockset[i].type == "unary_attribute_selector" ) { scasp_blockset[i]['mutator'] = "unary_attribute_selector_mutator" }; @@ -4015,7 +5169,7 @@ for (var i = 0; i < scasp_blockset.length; i++) { // This allows us to include reference definitions in the JSON above, but actually // use the custom JavaScript below to define blocks that it is awkward to build with JSON. -const excluded_block_types = ['new_attribute_declaration','new_object_category']; +const excluded_block_types = ['new_attribute_declaration','new_object_category','relationship_declaration']; for (var i = 0; i < scasp_blockset.length; i++) { const typename = scasp_blockset[i].type @@ -4031,6 +5185,126 @@ for (var i = 0; i < scasp_blockset.length; i++) { var headless=false; +Blockly.Blocks['relationship_declaration'] = { + init: function() { + this.appendDummyInput("topline") + .appendField(new Blockly.FieldTextInput("relationship_name"), "relationship_name") + .appendField("is a relationship between") + .appendField(new Blockly.FieldDropdown([["3","3"],["4","4"],["5","5"],["6","6"],["7","7"],["8","8"],["9","9"],["10","10"]]), "relationship_arity") + .appendField("objects or values, displayed as"); + var desc = this.appendDummyInput("description"); + for (var a=1; a< 3+1; a++) { + desc.appendField(new Blockly.FieldTextInput(""), "prefix" +a ); + desc.appendField(new Blockly.FieldDropdown(this.generateDataTypes), "type" + a); + } + desc.appendField(new Blockly.FieldTextInput(""), "postfix"); + this.setInputsInline(false); + this.setPreviousStatement(true, ["OUTER", "STATEMENT"]); + this.setNextStatement(true, "STATEMENT"); + this.setColour(30); + this.setTooltip("Use to declare a relationship between 3 or more objects or values."); + this.setHelpUrl("/docs/blocks/new_relationship/"); + }, + generateCategories: function() { + var allCategories = getAllCategories(); + if (allCategories.length) { + var optionList = []; + for (var i =0; i< allCategories.length; i++) { + optionList.push([allCategories[i],allCategories[i]]) + } + } else { + var optionList = [['No Categories Defined','none']]; + } + + return optionList; + }, + generateDataTypes: function() { + var options = [["number","number"], ["date","date"], ["time","time"], ["datetime","datetime"], ["duration","duration"], ['list','list']]; + var allCategories = getAllCategories(); + for (var i =0; i< allCategories.length; i++) { + options.push([allCategories[i],allCategories[i]]) + } + + return options; + }, + mutationToDom() { + // Store information required to reconstruct the block + let container = document.createElement('mutation'); + // At least 3 things exist, but those should be dealt with already. + // Now add the rest, if they exist in the block. + for (var n = 4; n <= 10; n++) { + if (this.getField('prefix'+n)) { + container.setAttribute('prefix'+n,this.getFieldValue('prefix'+n)); + container.setAttribute('type'+n,this.getFieldValue('type'+n)); + } + } + + return container; + }, + domToMutation(xmlElement) { + // Reformat the block based on the mutation. + // The values of the three mandatory ones will still be there in the XML. + // We need to add the fields and values for everything above that number. + var input = this.getInput('description'); + for (var n = 4; n <= 10; n++) { + if (xmlElement.hasAttribute('prefix'+n)) { // returns null if the attribute doesn't exist + // This one exists in the container. + // Add the corresponding fields, and set the values accordingly. + // If we are adding the fourth, the numbers are 6 and 7 for the prefix and type. + // If we are adding the fifth, the numbers are 8 and 9 for the prefix and type. + // So the numbers are n*2-2, and n*2-1 + var prefix_index = (n*2)-2; + var type_index = (n*2)-1; + input.insertFieldAt(prefix_index,new Blockly.FieldTextInput(""), "prefix" + n ); + this.getField('prefix'+n).value = xmlElement.getAttribute('prefix'+n); + input.insertFieldAt(type_index,new Blockly.FieldDropdown(this.generateDataTypes), "type" + n); + this.getField('type'+n).value = xmlElement.getAttribute('type'+n); // This is probably not going to work right away, because goddamned dropdowns suck. + } + } + } +} + +var updateRelationshipDeclaration; +updateRelationshipDeclaration = function(changeEvent) { + if (changeEvent.type == Blockly.Events.BLOCK_CHANGE && + changeEvent.element == "field" && + changeEvent.name == "relationship_arity" + ) { + + var arity = parseInt(changeEvent.newValue); + var old_arity = parseInt(changeEvent.oldValue); + var target = demoWorkspace.getBlockById(changeEvent.blockId); + var input = target.getInput('description'); + + if (arity > old_arity) { + // If there are 3, and the new value is 4, the indexes are 6 and 7. So the index + // is always the new arity times two minus 2 and 1. + // The current value of the postfix should be moved to the first new prefix. + var postfix_text = target.getFieldValue("postfix"); + for (var c = old_arity + 1 ; c <= arity; c++) { // Starts at 4, goes until newValue + var prefix_insert = (c*2)-2; + var type_insert = (c*2)-1; + input.insertFieldAt(prefix_insert,new Blockly.FieldTextInput(""), "prefix" + c ); + if (c == old_arity+1) { + target.getField("prefix" + c).setValue(postfix_text); + target.getField("postfix").setValue(""); + } + input.insertFieldAt(type_insert,new Blockly.FieldDropdown(target.generateDataTypes), "type" + c); + } + } else if (arity < old_arity) { + // If the number is smaller, removeField + var new_postfix = target.getFieldValue("prefix" + (arity+1)); + target.getField("postfix").setValue(new_postfix); + for (var c = old_arity; c > arity; c--) { + input.removeField("prefix"+c); + input.removeField("type"+c); + } + } + demoWorkspace.render(); + + } +}; + Blockly.Blocks['new_attribute_declaration'] = { init: function() { this.appendDummyInput() @@ -4085,7 +5359,6 @@ Blockly.Blocks['new_attribute_declaration'] = { this.getField('infix').setEnabled(true); this.getField('order').setEnabled(true); } - demoWorkspace.render(); }); }, generateCategories: function() { diff --git a/blawx/static/blawx/docs/images/blocks/new_relationship.png b/blawx/static/blawx/docs/images/blocks/new_relationship.png new file mode 100644 index 00000000..1b185608 Binary files /dev/null and b/blawx/static/blawx/docs/images/blocks/new_relationship.png differ diff --git a/blawx/static/blawx/docs/images/blocks/relationship_selector.png b/blawx/static/blawx/docs/images/blocks/relationship_selector.png new file mode 100644 index 00000000..ecfe90a3 Binary files /dev/null and b/blawx/static/blawx/docs/images/blocks/relationship_selector.png differ diff --git a/blawx/static/blawx/drawers.js b/blawx/static/blawx/drawers.js index 64c65b81..e5747e81 100644 --- a/blawx/static/blawx/drawers.js +++ b/blawx/static/blawx/drawers.js @@ -64,6 +64,55 @@ knownAttributesCallback = function(workspace) { demoWorkspace.registerToolboxCategoryCallback('KNOWN_ATTRIBUTES', knownAttributesCallback); +var knownRelationshipsCallback; +knownRelationshipsCallback = function(workspace) { + var xmlList = []; + var all_workspaces = getAllWorkspaces(); + for (var w = 0; w < all_workspaces.length; w++) { + // Go through the blocks in the workspace. + // If the block is a relationship declaration, add the relevant block to the xml + if (all_workspaces[w].xml_content) { + var domObject = Blockly.Xml.textToDom(all_workspaces[w].xml_content); + var tempWorkspace = new Blockly.Workspace(); + Blockly.Xml.domToWorkspace(domObject, tempWorkspace); + var blockList = tempWorkspace.getAllBlocks(); + for (var i = 0; i< blockList.length; i++) { + if (blockList[i].type == "relationship_declaration") { + var arity = parseInt(blockList[i].getFieldValue('relationship_arity')); + var relationship_name = blockList[i].getFieldValue('relationship_name'); + var blocktype = "relationship_selector" + arity; + var blockText = "" + // Add the mutator, which should include the name and the types + blockText += ""; + blockText += "" + blockList[i].getFieldValue("prefix2") + ""; + blockText += "" + blockList[i].getFieldValue("prefix3") + ""; + for (var param=4; param <= arity; param++) { + blockText += "" + blockList[i].getFieldValue("prefix" + param) + "" + } + blockText += "" + blockList[i].getFieldValue("postfix") + ""; + blockText += ""; + var block = Blockly.Xml.textToDom(blockText).firstChild; + // need to check for repeatedly adding the same block. + xmlList.push(block); + } + } + } + } + return xmlList; +} + +demoWorkspace.registerToolboxCategoryCallback('KNOWN_RELATIONSHIPS', knownRelationshipsCallback); var knownObjectsCallback; knownObjectsCallback = function(workspace) { diff --git a/blawx/static/blawx/examples/rps.yaml b/blawx/static/blawx/examples/rps.yaml index 2f00b07e..834b2b02 100644 --- a/blawx/static/blawx/examples/rps.yaml +++ b/blawx/static/blawx/examples/rps.yaml @@ -342,12 +342,11 @@ name="attribute_name">winnerplayerovthe winner ofobjectisvalueplayerthrowsignovobjectthrewvalueFALSEthrow3playerthrewsigningameFALSEFALSEgameplayed inPlayer2GamethrewPlayer1Throw1threwPlayer2Throw2beatsThrow1Throw2GamethrewinPlayer1Throw1GamethrewinPlayer2Throw2GamebeatsThrow1Throw2RPSA 4GamePlayer1 scasp_encoding: "blawx_attribute(game,winner,player).\nblawx_attribute_nlg(winner,ov,\"the - winner of\",\"is\",\"\").\n#pred winner(X,Y) :: 'the winner of @(X) is @(Y)'.\n#pred - holds(user,winner,X,Y) :: 'it is provided as a fact that the winner of @(X) - is @(Y)'.\n#pred holds(user,-winner,X,Y) :: 'it is provided as a fact that it - is not the case that the winner of @(X) is @(Y)'.\n#pred holds(Z,winner,X,Y) + winner of\",\"is\",\"\").\n:- dynamic winner/2.\n#pred winner(X,Y) :: 'the winner + of @(X) is @(Y)'.\n#pred holds(user,winner,X,Y) :: 'it is provided as a fact + that the winner of @(X) is @(Y)'.\n#pred holds(user,-winner,X,Y) :: 'it is provided + as a fact that it is not the case that the winner of @(X) is @(Y)'.\n#pred holds(Z,winner,X,Y) :: 'the conclusion in @(Z) that the winner of @(X) is @(Y) holds'.\n#pred holds(Z,-winner,X,Y) :: 'the conclusion in @(Z) that it is not the case that the winner of @(X) is @(Y) holds'.\n#pred according_to(Z,winner,X,Y) :: 'according to @(Z), the winner @@ -413,17 +414,85 @@ it is not the case that the winner of @(X) is @(Y)'.\n#pred blawx_defeated(Z,winner,X,Y) :: 'the conclusion in @(Z) that the winner of @(X) is @(Y) is defeated'.\n#pred blawx_defeated(Z,-winner,X,Y) :: 'the conclusion in @(Z) that the winner of - @(X) is @(Y) is defeated'.\nblawx_attribute(player,throw,sign).\nblawx_attribute_nlg(throw,ov,\"\",\"threw\",\"\").\n#pred - throw(X,Y) :: '@(X) threw @(Y)'.\n#pred holds(user,throw,X,Y) :: 'it is provided - as a fact that @(X) threw @(Y)'.\n#pred holds(user,-throw,X,Y) :: 'it is provided - as a fact that it is not the case that @(X) threw @(Y)'.\n#pred holds(Z,throw,X,Y) - :: 'the conclusion in @(Z) that @(X) threw @(Y) holds'.\n#pred holds(Z,-throw,X,Y) - :: 'the conclusion in @(Z) that it is not the case that @(X) threw @(Y) holds'.\n#pred - according_to(Z,throw,X,Y) :: 'according to @(Z), @(X) threw @(Y)'.\n#pred according_to(Z,-throw,X,Y) - :: 'according to @(Z), it is not the case that @(X) threw @(Y)'.\n#pred blawx_defeated(Z,throw,X,Y) - :: 'the conclusion in @(Z) that @(X) threw @(Y) is defeated'.\n#pred blawx_defeated(Z,-throw,X,Y) - :: 'the conclusion in @(Z) that @(X) threw @(Y) is defeated'.\n\naccording_to(sec_4_section,winner,Game,Player1) - :- game(Game),\nplayer(Player1),\nplayer(Player2),\nPlayer1 \\= Player2,\nplayer(Game,Player1),\nplayer(Game,Player2),\nthrow(Player1,Throw1),\nthrow(Player2,Throw2),\nbeats(Throw1,Throw2).\n\n% + @(X) is @(Y) is defeated'.\n#pred blawx_initially(winner(X,Y)) :: 'that the + winner of @(X) is @(Y) holds initially'.\n#pred blawx_initially(-winner(X,Y)) + :: 'that it is not the case that the winner of @(X) is @(Y) holds initially'.\n#pred + blawx_ultimately(winner(X,Y)) :: 'that the winner of @(X) is @(Y) holds ultimately'.\n#pred + blawx_ultimately(-winner(X,Y)) :: 'that it is not the case that the winner of + @(X) is @(Y) holds ultimately'.\n#pred blawx_as_of(winner(X,Y),T) :: 'that the + winner of @(X) is @(Y) holds at @(T)'.\n#pred blawx_as_of(-winner(X,Y),T) :: + 'that it is not the case that the winner of @(X) is @(Y) holds at @(T)'.\n#pred + blawx_during(T1,winner(X,Y),T2) :: 'that the winner of @(X) is @(Y) held between + @(T1) and @(T2)'.\n#pred blawx_during(T1,-winner(X,Y),T2) :: 'that it is not + the case that the winner of @(X) is @(Y) held between @(T1) and @(T2)'.\n#pred + blawx_becomes(winner(X,Y),T) :: 'that the winner of @(X) is @(Y) became true + at @(T)'.\n#pred blawx_becomes(-winner(X,Y),T) :: 'that it is not the case that + the winner of @(X) is @(Y) became true at @(T)'.\nblawx_as_of(winner(X,Y),datetime(Time)) + :- blawx_becomes(winner(X,Y),datetime(BeforeT)), not blawx_becomes(-winner(X,Y), + datetime(BetweenT)), BeforeT #< Time,BeforeT #< BetweenT, BetweenT #< Time.\nblawx_as_of(winner(X,Y),datetime(Time)) + :- blawx_initially(winner(X,Y)), not blawx_becomes(-winner(X,Y), datetime(BetweenT)), + BetweenT #< Time.\nblawx_during(datetime(Start),winner(X,Y),datetime(End)) :- + blawx_becomes(winner(X,Y),datetime(Start)), not blawx_becomes(-winner(X,Y),datetime(BeforeEnd)), + blawx_becomes(-winner(X,Y),datetime(End)), BeforeEnd #< End, Start #< End.\nblawx_during(datetime(bot),winner(X,Y),datetime(End)) + :- blawx_initially(winner(X,Y)), not blawx_becomes(-winner(X,Y),datetime(BeforeEnd)), + blawx_becomes(-winner(X,Y),datetime(End)), BeforeEnd #< End.\nblawx_during(datetime(Start),winner(X,Y),datetime(eot)) + :- blawx_becomes(winner(X,Y),datetime(Start)), not blawx_becomes(-winner(X,Y),datetime(AfterStart)), + blawx_ultimately(winner(X,Y)), AfterStart #> Start.\nblawx_as_of(-winner(X,Y),datetime(Time)) + :- blawx_becomes(-winner(X,Y),datetime(BeforeT)), not blawx_becomes(winner(X,Y), + datetime(BetweenT)), BeforeT #< Time,BeforeT #< BetweenT, BetweenT #< Time.\nblawx_as_of(-winner(X,Y),datetime(Time)) + :- blawx_initially(-winner(X,Y)), not blawx_becomes(winner(X,Y), datetime(BetweenT)), + BetweenT #< Time.\nblawx_during(datetime(Start),-winner(X,Y),datetime(End)) + :- blawx_becomes(-winner(X,Y),datetime(Start)), not blawx_becomes(winner(X,Y),datetime(BeforeEnd)), + blawx_becomes(winner(X,Y),datetime(End)), BeforeEnd #< End, Start #< End.\nblawx_during(datetime(bot),-winner(X,Y),datetime(End)) + :- blawx_initially(-winner(X,Y)), not blawx_becomes(winner(X,Y),datetime(BeforeEnd)), + blawx_becomes(winner(X,Y),datetime(End)), BeforeEnd #< End.\nblawx_during(datetime(Start),-winner(X,Y),datetime(eot)) + :- blawx_becomes(-winner(X,Y),datetime(Start)), not blawx_becomes(winner(X,Y),datetime(AfterStart)), + blawx_ultimately(-winner(X,Y)), AfterStart #> Start.\nblawx_relationship(throw,player,sign,game).\nblawx_relationship_nlg(throw,\"\",\"threw\",\"in\",\"\").\n:- + dynamic throw/3.\n#pred throw(A,B,C) :: '@(A) threw @(B) in @(C)'.\n#pred holds(user,throw,A,B,C) + :: 'it is provided as a fact that @(A) threw @(B) in @(C)'.\n#pred holds(user,-throw,A,B,C) + :: 'it is provided as a fact that it is not the case that @(A) threw @(B) in + @(C)'.\n#pred holds(Z,throw,A,B,C) :: 'the conclusion in @(Z) that @(A) threw + @(B) in @(C) holds'.\n#pred holds(Z,-throw,A,B,C) :: 'the conclusion in @(Z) + that it is not the case that @(A) threw @(B) in @(C) holds'.\n#pred according_to(Z,throw,A,B,C) + :: 'according to @(Z), @(A) threw @(B) in @(C)'.\n#pred according_to(Z,-throw,A,B,C) + :: 'according to @(Z), it is not the case that @(A) threw @(B) in @(C)'.\n#pred + blawx_defeated(Z,throw,A,B,C) :: 'the conclusion in @(Z) that @(A) threw @(B) + in @(C) is defeated'.\n#pred blawx_defeated(Z,-throw,A,B,C) :: 'the conclusion + in @(Z) that @(A) threw @(B) in @(C) is defeated'.\n#pred blawx_initially(throw(A,B,C)) + :: 'that @(A) threw @(B) in @(C) holds initially'.\n#pred blawx_initially(-throw(A,B,C)) + :: 'that it is not the case that @(A) threw @(B) in @(C) holds initially'.\n#pred + blawx_ultimately(throw(A,B,C)) :: 'that @(A) threw @(B) in @(C) holds ultimately'.\n#pred + blawx_ultimately(-throw(A,B,C)) :: 'that it is not the case that @(A) threw + @(B) in @(C) holds ultimately'.\n#pred blawx_as_of(throw(A,B,C),T) :: 'that + @(A) threw @(B) in @(C) holds at @(T)'.\n#pred blawx_as_of(-throw(A,B,C),T) + :: 'that it is not the case that @(A) threw @(B) in @(C) holds at @(T)'.\n#pred + blawx_during(T1,throw(A,B,C),T2) :: 'that @(A) threw @(B) in @(C) held between + @(T1) and @(T2)'.\n#pred blawx_during(T1,-throw(A,B,C),T2) :: 'that it is not + the case that @(A) threw @(B) in @(C) held between @(T1) and @(T2)'.\n#pred + blawx_becomes(throw(A,B,C),T) :: 'that @(A) threw @(B) in @(C) became true at + @(T)'.\n#pred blawx_becomes(-throw(A,B,C),T) :: 'that it is not the case that + @(A) threw @(B) in @(C) became true at @(T)'.\nblawx_as_of(throw(A,B,C),datetime(Time)) + :- blawx_becomes(throw(A,B,C),datetime(BeforeT)), not blawx_becomes(-throw(A,B,C), + datetime(BetweenT)), BeforeT #< Time,BeforeT #< BetweenT, BetweenT #< Time.\nblawx_as_of(throw(A,B,C),datetime(Time)) + :- blawx_initially(throw(A,B,C)), not blawx_becomes(-throw(A,B,C), datetime(BetweenT)), + BetweenT #< Time.\nblawx_during(datetime(Start),throw(A,B,C),datetime(End)) + :- blawx_becomes(throw(A,B,C),datetime(Start)), not blawx_becomes(-throw(A,B,C),datetime(BeforeEnd)), + blawx_becomes(-throw(A,B,C),datetime(End)), BeforeEnd #< End, Start #< End.\nblawx_during(datetime(bot),throw(A,B,C),datetime(End)) + :- blawx_initially(throw(A,B,C)), not blawx_becomes(-throwA,B,C),datetime(BeforeEnd)), + blawx_becomes(-throw(A,B,C),datetime(End)), BeforeEnd #< End.\nblawx_during(datetime(Start),throw(A,B,C),datetime(eot)) + :- blawx_becomes(throw(A,B,C),datetime(Start)), not blawx_becomes(-throw(A,B,C),datetime(AfterStart)), + blawx_ultimately(throw(A,B,C)), AfterStart #> Start.\nblawx_as_of(-throw(A,B,C),datetime(Time)) + :- blawx_becomes(-throw(A,B,C),datetime(BeforeT)), not blawx_becomes(throw(A,B,C), + datetime(BetweenT)), BeforeT #< Time,BeforeT #< BetweenT, BetweenT #< Time.\nblawx_as_of(-throw(A,B,C),datetime(Time)) + :- blawx_initially(-throw(A,B,C)), not blawx_becomes(throw(A,B,C), datetime(BetweenT)), + BetweenT #< Time.\nblawx_during(datetime(Start),-throw(A,B,C),datetime(End)) + :- blawx_becomes(-throw(A,B,C),datetime(Start)), not blawx_becomes(throw(A,B,C),datetime(BeforeEnd)), + blawx_becomes(throw(A,B,C),datetime(End)), BeforeEnd #< End, Start #< End.\nblawx_during(datetime(bot),-throw(A,B,C),datetime(End)) + :- blawx_initially(-throw(A,B,C)), not blawx_becomes(throw(A,B,C),datetime(BeforeEnd)), + blawx_becomes(throw(A,B,C),datetime(End)), BeforeEnd #< End.\nblawx_during(datetime(Start),-throw(A,B,C),datetime(eot)) + :- blawx_becomes(-throw(A,B,C),datetime(Start)), not blawx_becomes(throw(A,B,C),datetime(AfterStart)), + blawx_ultimately(-throw(A,B,C)), AfterStart #> Start.\n\naccording_to(sec_4_section,winner,Game,Player1) + :- game(Game),\nplayer(Player1),\nplayer(Player2),\nPlayer1 \\= Player2,\nplayer(Game,Player1),\nplayer(Game,Player2),\nthrow(Player1,Throw1,Game),\nthrow(Player2,Throw2,Game),\nbeats(Throw1,Throw2).\n\n% BLAWX CHECK DUPLICATES\nholds(sec_4_section,winner,Game,Player1) :- according_to(sec_4_section,winner,Game,Player1).\n\n% BLAWX CHECK DUPLICATES\n winner(Game,Player1) :- holds(sec_4_section,winner,Game,Player1)." - model: blawx.blawxtest @@ -457,23 +526,30 @@ objectname="jane">janetestgamethrewjanerockthrewbobscissorstestgamethrewinjanerocktestgamethrewinbobscissorstestgamethe winner ofisABthrewABthrewinABCWe ask specifically whether bob won any games so that we don't get the same three answers twice, once for each possible player. Start.\n'; + code += 'blawx_as_of(-' + text_relationship_name + '(' + parameters + '),datetime(Time)) :- blawx_becomes(-' + text_relationship_name + '(' + parameters + '),datetime(BeforeT)), not blawx_becomes(' + text_relationship_name + '(' + parameters + '), datetime(BetweenT)), BeforeT #< Time,BeforeT #< BetweenT, BetweenT #< Time.\n'; + code += 'blawx_as_of(-' + text_relationship_name + '(' + parameters + '),datetime(Time)) :- blawx_initially(-' + text_relationship_name + '(' + parameters + ')), not blawx_becomes(' + text_relationship_name + '(' + parameters + '), datetime(BetweenT)), BetweenT #< Time.\n'; + code += 'blawx_during(datetime(Start),-' + text_relationship_name + '(' + parameters + '),datetime(End)) :- blawx_becomes(-' + text_relationship_name + '(' + parameters + '),datetime(Start)), not blawx_becomes(' + text_relationship_name + '(' + parameters + '),datetime(BeforeEnd)), blawx_becomes(' + text_relationship_name + '(' + parameters + '),datetime(End)), BeforeEnd #< End, Start #< End.\n'; + code += 'blawx_during(datetime(bot),-' + text_relationship_name + '(' + parameters + '),datetime(End)) :- blawx_initially(-' + text_relationship_name + '(' + parameters + ')), not blawx_becomes(' + text_relationship_name + '(' + parameters + '),datetime(BeforeEnd)), blawx_becomes(' + text_relationship_name + '(' + parameters + '),datetime(End)), BeforeEnd #< End.\n'; + code += 'blawx_during(datetime(Start),-' + text_relationship_name + '(' + parameters + '),datetime(eot)) :- blawx_becomes(-' + text_relationship_name + '(' + parameters + '),datetime(Start)), not blawx_becomes(' + text_relationship_name + '(' + parameters + '),datetime(AfterStart)), blawx_ultimately(-' + text_relationship_name + '(' + parameters + ')), AfterStart #> Start.\n'; + return code; +}; + +sCASP['relationship_selector3'] = function(block) { + var value_parameter1 = sCASP.valueToCode(block, 'parameter1', sCASP.ORDER_ATOMIC); + var value_parameter2 = sCASP.valueToCode(block, 'parameter2', sCASP.ORDER_ATOMIC); + var value_parameter3 = sCASP.valueToCode(block, 'parameter3', sCASP.ORDER_ATOMIC); + var code = this.relationship_name + "(" + value_parameter1 + "," + value_parameter2 + "," + value_parameter3 + ")"; + return code; + }; + + sCASP['relationship_selector4'] = function(block) { + var value_parameter1 = sCASP.valueToCode(block, 'parameter1', sCASP.ORDER_ATOMIC); + var value_parameter2 = sCASP.valueToCode(block, 'parameter2', sCASP.ORDER_ATOMIC); + var value_parameter3 = sCASP.valueToCode(block, 'parameter3', sCASP.ORDER_ATOMIC); + var value_parameter4 = sCASP.valueToCode(block, 'parameter4', sCASP.ORDER_ATOMIC); + var code = this.relationship_name + "(" + value_parameter1 + "," + value_parameter2 + "," + value_parameter3 + "," + value_parameter4 + ")"; + return code; + }; + + sCASP['relationship_selector5'] = function(block) { + var value_parameter1 = sCASP.valueToCode(block, 'parameter1', sCASP.ORDER_ATOMIC); + var value_parameter2 = sCASP.valueToCode(block, 'parameter2', sCASP.ORDER_ATOMIC); + var value_parameter3 = sCASP.valueToCode(block, 'parameter3', sCASP.ORDER_ATOMIC); + var value_parameter4 = sCASP.valueToCode(block, 'parameter4', sCASP.ORDER_ATOMIC); + var value_parameter5 = sCASP.valueToCode(block, 'parameter5', sCASP.ORDER_ATOMIC); + var code = this.relationship_name + "(" + value_parameter1 + "," + value_parameter2 + "," + value_parameter3 + "," + value_parameter4 + "," + value_parameter5 + ")"; + return code; + }; + + sCASP['relationship_selector6'] = function(block) { + var value_parameter1 = sCASP.valueToCode(block, 'parameter1', sCASP.ORDER_ATOMIC); + var value_parameter2 = sCASP.valueToCode(block, 'parameter2', sCASP.ORDER_ATOMIC); + var value_parameter3 = sCASP.valueToCode(block, 'parameter3', sCASP.ORDER_ATOMIC); + var value_parameter4 = sCASP.valueToCode(block, 'parameter4', sCASP.ORDER_ATOMIC); + var value_parameter5 = sCASP.valueToCode(block, 'parameter5', sCASP.ORDER_ATOMIC); + var value_parameter6 = sCASP.valueToCode(block, 'parameter6', sCASP.ORDER_ATOMIC); + var code = this.relationship_name + "(" + value_parameter1 + "," + value_parameter2 + "," + value_parameter3 + "," + value_parameter4 + "," + value_parameter5 + "," + value_parameter6 + ")"; + return code; + }; + + sCASP['relationship_selector7'] = function(block) { + var value_parameter1 = sCASP.valueToCode(block, 'parameter1', sCASP.ORDER_ATOMIC); + var value_parameter2 = sCASP.valueToCode(block, 'parameter2', sCASP.ORDER_ATOMIC); + var value_parameter3 = sCASP.valueToCode(block, 'parameter3', sCASP.ORDER_ATOMIC); + var value_parameter4 = sCASP.valueToCode(block, 'parameter4', sCASP.ORDER_ATOMIC); + var value_parameter5 = sCASP.valueToCode(block, 'parameter5', sCASP.ORDER_ATOMIC); + var value_parameter6 = sCASP.valueToCode(block, 'parameter6', sCASP.ORDER_ATOMIC); + var value_parameter7 = sCASP.valueToCode(block, 'parameter7', sCASP.ORDER_ATOMIC); + var code = this.relationship_name + "(" + value_parameter1 + "," + value_parameter2 + "," + value_parameter3 + "," + value_parameter4 + "," + value_parameter5 + "," + value_parameter6 + "," + value_parameter7 + ")"; + return code; + }; + + sCASP['relationship_selector8'] = function(block) { + var value_parameter1 = sCASP.valueToCode(block, 'parameter1', sCASP.ORDER_ATOMIC); + var value_parameter2 = sCASP.valueToCode(block, 'parameter2', sCASP.ORDER_ATOMIC); + var value_parameter3 = sCASP.valueToCode(block, 'parameter3', sCASP.ORDER_ATOMIC); + var value_parameter4 = sCASP.valueToCode(block, 'parameter4', sCASP.ORDER_ATOMIC); + var value_parameter5 = sCASP.valueToCode(block, 'parameter5', sCASP.ORDER_ATOMIC); + var value_parameter6 = sCASP.valueToCode(block, 'parameter6', sCASP.ORDER_ATOMIC); + var value_parameter7 = sCASP.valueToCode(block, 'parameter7', sCASP.ORDER_ATOMIC); + var value_parameter8 = sCASP.valueToCode(block, 'parameter8', sCASP.ORDER_ATOMIC); + var code = this.relationship_name + "(" + value_parameter1 + "," + value_parameter2 + "," + value_parameter3 + "," + value_parameter4 + "," + value_parameter5 + "," + value_parameter6 + "," + value_parameter7 + "," + value_parameter8 + ")"; + return code; + }; + + sCASP['relationship_selector9'] = function(block) { + var value_parameter1 = sCASP.valueToCode(block, 'parameter1', sCASP.ORDER_ATOMIC); + var value_parameter2 = sCASP.valueToCode(block, 'parameter2', sCASP.ORDER_ATOMIC); + var value_parameter3 = sCASP.valueToCode(block, 'parameter3', sCASP.ORDER_ATOMIC); + var value_parameter4 = sCASP.valueToCode(block, 'parameter4', sCASP.ORDER_ATOMIC); + var value_parameter5 = sCASP.valueToCode(block, 'parameter5', sCASP.ORDER_ATOMIC); + var value_parameter6 = sCASP.valueToCode(block, 'parameter6', sCASP.ORDER_ATOMIC); + var value_parameter7 = sCASP.valueToCode(block, 'parameter7', sCASP.ORDER_ATOMIC); + var value_parameter8 = sCASP.valueToCode(block, 'parameter8', sCASP.ORDER_ATOMIC); + var value_parameter9 = sCASP.valueToCode(block, 'parameter9', sCASP.ORDER_ATOMIC); + var code = this.relationship_name + "(" + value_parameter1 + "," + value_parameter2 + "," + value_parameter3 + "," + value_parameter4 + "," + value_parameter5 + "," + value_parameter6 + "," + value_parameter7 + "," + value_parameter8 + "," + value_parameter9 + ")"; + return code; + }; + + sCASP['relationship_selector10'] = function(block) { + var value_parameter1 = sCASP.valueToCode(block, 'parameter1', sCASP.ORDER_ATOMIC); + var value_parameter2 = sCASP.valueToCode(block, 'parameter2', sCASP.ORDER_ATOMIC); + var value_parameter3 = sCASP.valueToCode(block, 'parameter3', sCASP.ORDER_ATOMIC); + var value_parameter4 = sCASP.valueToCode(block, 'parameter4', sCASP.ORDER_ATOMIC); + var value_parameter5 = sCASP.valueToCode(block, 'parameter5', sCASP.ORDER_ATOMIC); + var value_parameter6 = sCASP.valueToCode(block, 'parameter6', sCASP.ORDER_ATOMIC); + var value_parameter7 = sCASP.valueToCode(block, 'parameter7', sCASP.ORDER_ATOMIC); + var value_parameter8 = sCASP.valueToCode(block, 'parameter8', sCASP.ORDER_ATOMIC); + var value_parameter9 = sCASP.valueToCode(block, 'parameter9', sCASP.ORDER_ATOMIC); + var value_parameter10 = sCASP.valueToCode(block, 'parameter10', sCASP.ORDER_ATOMIC); + var code = this.relationship_name + "(" + value_parameter1 + "," + value_parameter2 + "," + value_parameter3 + "," + value_parameter4 + "," + value_parameter5 + "," + value_parameter6 + "," + value_parameter7 + "," + value_parameter8 + "," + value_parameter9 + "," + value_parameter10 + ")"; + return code; + }; + function deconstruct_term(term) { var elements = []; const term_pattern = /(?[^\(\)]*)\((?.*)\)/gm diff --git a/blawx/templates/blawx/blawx.html b/blawx/templates/blawx/blawx.html index b9192bbc..01b9363b 100644 --- a/blawx/templates/blawx/blawx.html +++ b/blawx/templates/blawx/blawx.html @@ -54,6 +54,7 @@ + @@ -109,6 +110,8 @@ + + @@ -205,6 +208,7 @@ myob.observe(blocklyArea); Blockly.svgResize(demoWorkspace); demoWorkspace.addChangeListener(onCategoryChange); + demoWorkspace.addChangeListener(updateRelationshipDeclaration); var knownCategories = []; var localCategories = []; window.onload = function() { diff --git a/blawx/templates/blawx/docs.html b/blawx/templates/blawx/docs.html index f9100b6a..2e6ef10c 100644 --- a/blawx/templates/blawx/docs.html +++ b/blawx/templates/blawx/docs.html @@ -161,7 +161,7 @@ diff --git a/blawx/templates/blawx/scenario_editor.html b/blawx/templates/blawx/scenario_editor.html index 1a5c39b7..0e328ef7 100644 --- a/blawx/templates/blawx/scenario_editor.html +++ b/blawx/templates/blawx/scenario_editor.html @@ -141,8 +141,12 @@
View
Devel
- This tab shows the payload sent to the Blawx interview API, and the response + This tab shows the ontology received from the ontology API, the payload sent to the Blawx interview API, and the response received, to illustrate use of the Blawx interview API for developers. +
Ontology
+
+ +
Payload
@@ -703,7 +707,7 @@
Response
if (predicate_name == "gt") { return displayValue(model.args[0],human) + " is greater than or equal to" + displayValue(model.args[1],human) } - predicate_type = model.args.length; // 1 is category, 2 is attribute + predicate_type = model.args.length; // 1 is category, 2 is attribute (not any more), 3+ is relationship var prefix = ""; var infix = ""; var postfix = ""; @@ -727,7 +731,7 @@
Response
} } return displayValue(object,human) + " is a " + predicate_name; - } else { // it is an attribute + } else if (predicate_type == 2) { // it is a binary attribute object = model.args[0]; value = model.args[1]; @@ -746,6 +750,25 @@
Response
} } return displayValue(object,human) + "'s " + predicate_name + " is " + displayValue(value,human); + } else { // It is a relationship + var postfix = ""; + var prefixes = {}; + var arity = model.args.length; + var output = "" + for (var i=0; i < ontology.RelationshipNLG.length; i++) { + if (ontology.RelationshipNLG[i].Relationship = predicate_name) { + postfix = ontology.RelationshipNLG[i].Postfix; + for (var p=1; p<=arity; p++) { + prefixes[p] = ontology.RelationshipNLG[i]['Prefix'+p]; + } + break; + } + } + for (var p=1; p <= arity; p++) { + output += prefixes[p] + " " + displayValue(model.args[p-1],human) + " "; + } + output += postfix; + return output; } } } @@ -757,6 +780,7 @@
Response
objects = ontology['Objects']; attributes = ontology['Attributes']; values = ontology['Values']; + relations = ontology['Relations']; for (var i=0; i < objects.length; i++) { var new_fact_statement = {'from_ontology': true, 'type': 'true','category': objects[i]['Category'], 'object': objects[i]['Object']} new_fact_data['facts'].push(new_fact_statement); @@ -778,6 +802,14 @@
Response
} new_fact_data['facts'].push(new_fact_statement); } + relationships = ontology['Relationships']; + for (var r=0; r < relations.length; r++) { + var new_relation = {'from_ontology': true, 'type': 'true', 'relationship': relations[r]['Relationship']} + for (var p=1; p <= Object.keys(relations[r]).length-1; p++) { + new_relation['parameter'+p] = relations[r]['Parameter'+p] + } + new_fact_data['facts'].push(new_relation); + } } @@ -840,7 +872,7 @@
Response
object_type = ontology['Attributes'][a]['Category']; value_type = ontology['Attributes'][a]['Type']; var value_type_is_category; - if (['date','time','datetime','duration','number'].includes(value_type)) { + if (['date','time','datetime','duration','number','list'].includes(value_type)) { value_type_is_category = false; } else { value_type_is_category = true; @@ -1017,58 +1049,138 @@
Response
output_html += '
'; } } - output_html += '
'; - output_html += ''; + output_html += '
'; output_html += ''; @@ -1077,6 +1189,66 @@
Response
target.outerHTML = output_html; }; + function generate_field_control(relationship_name,parameter,value_type) { + var value_html = ""; + switch(value_type) { + case 'number': + value_html += '
'; + value_html += ''; + value_html += "
"; + break; + case 'date': + value_html += '
'; + //value_html += ''; + value_html += ''; + value_html += "
"; + break; + case 'duration': + value_html += '
'; + //value_html += ''; + value_html += 'S'; + value_html += '
'; + value_html += ''; + value_html += '
'; + value_html += 'D'; + value_html += ''; + value_html += 'H'; + value_html += ''; + value_html += 'M'; + value_html += ''; + value_html += "
"; + break; + case 'boolean': + break; + case 'time': + value_html += '
'; + value_html += ''; + value_html += "
"; + break; + case 'datetime': + value_html += '
'; + value_html += ''; + value_html += "
"; + break; + default: + if (ontology['Categories'].includes(value_type)) { + value_html += '
'; + value_html += '
'; + } else { + value_html += "Can't Render Datatype"; + } + } + return value_html; + } function toggle_unground_new_object(category) { // Get the value of the checkbox var checkbox = document.getElementById('new_object_toggle_check_' + category); @@ -1103,6 +1275,10 @@
Response
function show_new_attribute(attribute) { target = document.getElementById('new_attribute_' + attribute); target.classList.add('show'); + }; + function show_new_relationship(relationship) { + target = document.getElementById('new_relationship_' + relationship); + target.classList.add('show'); } function save_new_object(category){ // Add the object to the data @@ -1120,6 +1296,72 @@
Response
// redraw draw_facts(); }; + function save_new_relationship(relationship) { + var target_truth_value = document.getElementById('new_relationship_truth_type_' + relationship); + var new_relationship_statement = {'from_ontology': false, 'relationship': relationship, 'type': target_truth_value.value} + // I Need to get the Arity of the relationship + var arity = 3; + var types = {}; + for (var r = 0; r < ontology['Relationships'].length; r++) { + if (relationship == ontology['Relationships'][r]['Relationship']) { + arity = Object.keys(ontology['Relationships'][r]).length-1; + for (var p=1; p<=arity; p++) { + types[p] = ontology['Relationships'][r]['Parameter'+p]; + } + break; + } + } + // Now I need to get the values for all of the parameters + var variables = "ABCDEFGHIJK"; + for (var p = 1; p <= arity; p++) { + if (types[p] == "duration") { + // Get the new value + var new_value = ""; + var direction_target = document.getElementById('new_relationship_parameter_' + p + '_' + relationship + '_direction'); + var day_target = document.getElementById('new_relationship_parameter_' + p + '_' + relationship + '_days'); + var hour_target = document.getElementById('new_relationship_parameter_' + p + '_' + relationship + '_hours'); + var minute_target = document.getElementById('new_relationship_parameter_' + p + '_' + relationship + '_minutes'); + if (direction_target.checked) { + new_direction = true; + } else { + new_direction = false; + } + var new_day = day_target.value; + var new_hour = hour_target.value; + var new_minute = minute_target.value; + if (new_direction) { + new_value = ""; + } else { + new_value = "-"; + } + new_value += "P" + // The idea here is that if all three are zero, it should come out as P0D + if (parseInt(new_day) || (!parseInt(new_year) && !parseInt(new_month))) { + new_value += new_day + "D"; + } + if (parseInt(new_hour) || parseInt(new_minute)) { + new_value += "T"; + } + if (parseInt(new_hour)) { + new_value += new_hour + "H"; + } + if (parseInt(new_minute)) { + new_value += new_minute + "M"; + } + target_value = new_value; + } else { + target_param = document.getElementById('new_relationship_parameter_' + p + '_' + relationship); + target_value = target_param.value; + } + if (target_value == "VAR") { + new_relationship_statement['parameter'+p] = {'variable': variables[p]}; + } else { + new_relationship_statement['parameter'+p] = target_value; + } + } + new_fact_data['facts'].push(new_relationship_statement); + draw_facts(); + } function cancel_new_object(category){ // Delete the value in the current new object //target_new_object = document.getElementById('category_' + category + '_new_object'); @@ -1134,6 +1376,10 @@
Response
function cancel_new_value(attribute){ target_attribute = document.getElementById('new_attribute_' + attribute); target_attribute.classList.remove('show'); + }; + function cancel_new_relationship(relationship) { + target = document.getElementById('new_relationship_' + relationship); + target.classList.remove('show'); } function show_new_value(category,object,attribute){ // Close any other open new object or value @@ -1248,6 +1494,7 @@
Response
var answer_element = document.getElementById('answers'); var payload_element = document.getElementById('payload'); var response_element = document.getElementById('response'); + var ontology_element = document.getElementById('ontology'); function run_test() { var testrun_request = new XMLHttpRequest(); testrun_request.onload = function () { @@ -1256,6 +1503,8 @@
Response
payload_element.innerHTML = '
' + JSON.stringify(new_fact_data,null,2) + '
' response_element.innerHTML = '
' + JSON.stringify(parsed_test_response,null,2) + '
' + + ontology_element.innerHTML = '
' + JSON.stringify(ontology,null,2) + '
' // If the question is answered if (parsed_test_response['Answers'].length) { // Display the answer @@ -1398,6 +1647,19 @@
Response
output += '
'; output += ''; } + // For each relationship + for (var k=0; k < ontology['Relationships'].length; k++) { + output += '
  • ' + output += '
    '; + output += 'Hide Relationship ' + ontology['Relationships'][k]['Relationship'] + ''; + output += '
    '; + output += '
  • '; + } output += ''; view_form_element.innerHTML = output; } @@ -1438,10 +1700,14 @@
    Response
    if (hidden_by_view.includes('view_cat_' + new_fact_data['facts'][f]['category'])) { hidden = true; } - } else { + } else if ('attribute' in new_fact_data['facts'][f]) { if (hidden_by_view.includes('view_att_' + new_fact_data['facts'][f]['attribute'])) { hidden = true; } + } else if ('relationship' in new_fact_data['facts'][f]) { + if (hidden_by_view.includes('view_rel_' + new_fact_data['facts'][f]['relationship'])) { + hidden = true; + } } if (!hidden) { output_html += "
  • "; @@ -1471,7 +1737,7 @@
    Response
    object_display = "any object" } output_html += prefix + ' ' + object_display + ' ' + postfix; - } else { + } else if ('attribute' in new_fact_data['facts'][f]) { var attribute_name = new_fact_data['facts'][f]['attribute']; for (var i=0; i< ontology['AttributeNLG'].length; i++) { if (attribute_name == ontology['AttributeNLG'][i]['Attribute']) { @@ -1548,6 +1814,79 @@
    Response
    } else { output_html += prefix + ' ' + object_display + ' ' + postfix ; } + } else if ('relationship' in new_fact_data['facts'][f]) { + var arity = 3; + var prefixes = {} + var postfix = ""; + for (var i=0; i < ontology['RelationshipNLG'].length; i++) { + + if (ontology['RelationshipNLG'][i]['Relationship'] == new_fact_data['facts'][f]['relationship']) { + postfix = ontology['RelationshipNLG'][i]['Postfix']; + arity = Object.keys(ontology['RelationshipNLG'][i]).length-2; + for (var p=1; p <= arity; p++) { + prefixes[p] = ontology['RelationshipNLG'][i]['Prefix'+p]; + } + break; + } + } + var types = {} + for (var i=0; i < ontology['Relationships'].length; i++) { + if (ontology['Relationships'][i]['Relationship'] == new_fact_data['facts'][f]['relationship']) { + for (var p=1; p <= arity; p++) { + types[p] = ontology['Relationships'][i]['Parameter'+p]; + } + break; + } + } + for (var i=1; i <= arity; i++) { + output_html += " " + prefixes[i]; + var value_display = new_fact_data['facts'][f]['parameter'+i]; + var value_type = types[i]; + if (typeof(value_display) == 'object') { + value_display = "any " + value_type; + } + if (value_type == "duration") { + iso_duration = /^(-)?P(\d+Y)?(\d+M)?(\d+D)?T?(\d+H)?(\d+M)?(\d+S)?$/ + matches = iso_duration.exec(value_display) + var new_value_display = "" + var future = true; + if (matches[1] != undefined) { + future = false; + } + if (matches[2] != undefined) { + new_value_display += matches[2].slice(0,-1) + " years, "; + } + if (matches[3] != undefined) { + new_value_display += matches[3].slice(0,-1) + " months, "; + } + if (matches[4] != undefined) { + new_value_display += matches[4].slice(0,-1) + " days, "; + } + if (matches[5] != undefined) { + new_value_display += matches[5].slice(0,-1) + " hours, "; + } + if (matches[6] != undefined) { + new_value_display += matches[6].slice(0,-1) + " minutes, "; + } + if (matches[7] != undefined) { + new_value_display += matches[7].slice(0,-1) + " seconds, "; + } + if (future) { + new_value_display += " into the future"; + } else { + new_value_display += " into the past"; + } + var last_comma = new_value_display.lastIndexOf(','); + value_display = new_value_display.slice(0,last_comma) + new_value_display.slice(last_comma+1); + + } + if (value_type == "datetime") { + value_display = value_display.replace("T"," ") + } + output_html += " " + value_display; + } + output_html += " " + postfix; + // TODO: This doesn't deal with variables, and it doesn't format data properly. } if (!new_fact_data['facts'][f]['from_ontology']) { var delete_target diff --git a/blawx/templates/blawx/test.html b/blawx/templates/blawx/test.html index f87e7fb6..18127256 100644 --- a/blawx/templates/blawx/test.html +++ b/blawx/templates/blawx/test.html @@ -52,6 +52,7 @@ + @@ -107,6 +108,8 @@ + + @@ -212,6 +215,7 @@ } demoWorkspace.addChangeListener(onCategoryChange); + demoWorkspace.addChangeListener(updateRelationshipDeclaration); var knownCategories = []; var localCategories = []; window.onload = function() { diff --git a/blawx/util/blawx_block_definitions.json b/blawx/util/blawx_block_definitions.json index e2f62cca..2dc8d288 100644 --- a/blawx/util/blawx_block_definitions.json +++ b/blawx/util/blawx_block_definitions.json @@ -3967,4 +3967,1155 @@ "colour": 330, "tooltip": "Generate a duration from a numerical timestamp value", "helpUrl": "/docs/blocks/duration_from_ts" +}, +{ + "type": "relationship_declaration", + "message0": "%1 is a relationship between %2 objects or values described as %3 %4 %5 %6 %7 %8 %9 %10", + "args0": [ + { + "type": "field_input", + "name": "relationship_name", + "text": "relationship_name" + }, + { + "type": "field_dropdown", + "name": "arity", + "options": [ + [ + "3", + "3" + ], + [ + "4", + "4" + ], + [ + "5", + "5" + ], + [ + "6", + "6" + ], + [ + "7", + "7" + ], + [ + "8", + "8" + ], + [ + "9", + "9" + ], + [ + "10", + "10" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "field_input", + "name": "prefix1", + "text": "" + }, + { + "type": "field_dropdown", + "name": "type1", + "options": [ + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ] + ] + }, + { + "type": "field_input", + "name": "prefix2", + "text": "" + }, + { + "type": "field_dropdown", + "name": "type2", + "options": [ + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ] + ] + }, + { + "type": "field_input", + "name": "prefix3", + "text": "" + }, + { + "type": "field_dropdown", + "name": "type3", + "options": [ + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ] + ] + }, + { + "type": "field_input", + "name": "postfix", + "text": "" + } + ], + "previousStatement": [ + "OUTER", + "STATEMENT" + ], + "nextStatement": "STATEMENT", + "colour": 30, + "tooltip": "Use to declare a relationship between 3 or more objects or values.", + "helpUrl": "/docs/blocks/new_relationship/" +}, +{ + "type": "relationship_selector", + "message0": "%1 %2 %3 %4 %5 %6 %7", + "args0": [ + { + "type": "field_label_serializable", + "name": "prefix1", + "text": "prefix1" + }, + { + "type": "input_value", + "name": "first_element" + }, + { + "type": "field_label_serializable", + "name": "prefix2", + "text": "prefix2" + }, + { + "type": "input_value", + "name": "second_element" + }, + { + "type": "field_label_serializable", + "name": "prefix3", + "text": "prefix3" + }, + { + "type": "input_value", + "name": "third_element" + }, + { + "type": "field_label_serializable", + "name": "postfix", + "text": "postfix" + } + ], + "inputsInline": true, + "previousStatement": [ + "OUTER", + "STATEMENT" + ], + "nextStatement": "STATEMENT", + "colour": 150, + "tooltip": "Use to set or check the value of a relationship.", + "helpUrl": "/docs/blocks/relationship_selector/" +}, +{ + "type": "relationship_ddeclaration", + "message0": "%1 is a relationship between %2 objects or values described as %3 %4 %5 %6 %7 %8 %9 %10", + "args0": [ + { + "type": "field_input", + "name": "relationship_name", + "text": "relationship_name" + }, + { + "type": "field_dropdown", + "name": "arity", + "options": [ + [ + "3", + "3" + ], + [ + "4", + "4" + ], + [ + "5", + "5" + ], + [ + "6", + "6" + ], + [ + "7", + "7" + ], + [ + "8", + "8" + ], + [ + "9", + "9" + ], + [ + "10", + "10" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "field_input", + "name": "prefix1", + "text": "" + }, + { + "type": "field_dropdown", + "name": "type1", + "options": [ + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ] + ] + }, + { + "type": "field_input", + "name": "prefix2", + "text": "" + }, + { + "type": "field_dropdown", + "name": "type2", + "options": [ + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ] + ] + }, + { + "type": "field_input", + "name": "prefix3", + "text": "" + }, + { + "type": "field_dropdown", + "name": "type3", + "options": [ + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ], + [ + "option", + "OPTIONNAME" + ] + ] + }, + { + "type": "field_input", + "name": "postfix", + "text": "" + } + ], + "previousStatement": [ + "OUTER", + "STATEMENT" + ], + "nextStatement": "STATEMENT", + "colour": 30, + "tooltip": "Use to declare a relationship between 3 or more objects or values.", + "helpUrl": "/docs/blocks/new_relationship/" +}, +{ + "type": "relationship_selector3", + "message0": "%1 %2 %3 %4 %5 %6 %7", + "args0": [ + { + "type": "field_label_serializable", + "name": "prefix1", + "text": "prefix1" + }, + { + "type": "input_value", + "name": "parameter1", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix2", + "text": "prefix2" + }, + { + "type": "input_value", + "name": "parameter2", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix3", + "text": "prefix3" + }, + { + "type": "input_value", + "name": "parameter3", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "postfix", + "text": "postfix" + } + ], + "inputsInline": true, + "previousStatement": [ + "OUTER", + "STATEMENT" + ], + "nextStatement": "STATEMENT", + "colour": 195, + "tooltip": "Use to set or check the value of a relationship.", + "helpUrl": "/docs/blocks/relationship_selector/" +}, +{ + "type": "relationship_selector4", + "message0": "%1 %2 %3 %4 %5 %6 %7 %8 %9", + "args0": [ + { + "type": "field_label_serializable", + "name": "prefix1", + "text": "prefix1" + }, + { + "type": "input_value", + "name": "parameter1", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix2", + "text": "prefix2" + }, + { + "type": "input_value", + "name": "parameter2", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix3", + "text": "prefix3" + }, + { + "type": "input_value", + "name": "parameter3", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix4", + "text": "prefix4" + }, + { + "type": "input_value", + "name": "parameter4", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "postfix", + "text": "postfix" + } + ], + "inputsInline": true, + "previousStatement": [ + "OUTER", + "STATEMENT" + ], + "nextStatement": "STATEMENT", + "colour": 195, + "tooltip": "Use to set or check the value of a relationship.", + "helpUrl": "/docs/blocks/relationship_selector/" +}, +{ + "type": "relationship_selector5", + "message0": "%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11", + "args0": [ + { + "type": "field_label_serializable", + "name": "prefix1", + "text": "prefix1" + }, + { + "type": "input_value", + "name": "parameter1", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix2", + "text": "prefix2" + }, + { + "type": "input_value", + "name": "parameter2", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix3", + "text": "prefix3" + }, + { + "type": "input_value", + "name": "parameter3", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix4", + "text": "prefix4" + }, + { + "type": "input_value", + "name": "parameter4", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix5", + "text": "prefix5" + }, + { + "type": "input_value", + "name": "parameter5", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "postfix", + "text": "postfix" + } + ], + "inputsInline": true, + "previousStatement": [ + "OUTER", + "STATEMENT" + ], + "nextStatement": "STATEMENT", + "colour": 195, + "tooltip": "Use to set or check the value of a relationship.", + "helpUrl": "/docs/blocks/relationship_selector/" +}, +{ + "type": "relationship_selector6", + "message0": "%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13", + "args0": [ + { + "type": "field_label_serializable", + "name": "prefix1", + "text": "prefix1" + }, + { + "type": "input_value", + "name": "parameter1", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix2", + "text": "prefix2" + }, + { + "type": "input_value", + "name": "parameter2", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix3", + "text": "prefix3" + }, + { + "type": "input_value", + "name": "parameter3", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix4", + "text": "prefix4" + }, + { + "type": "input_value", + "name": "parameter4", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix5", + "text": "prefix5" + }, + { + "type": "input_value", + "name": "parameter5", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix6", + "text": "prefix6" + }, + { + "type": "input_value", + "name": "parameter6", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "postfix", + "text": "postfix" + } + ], + "inputsInline": true, + "previousStatement": [ + "OUTER", + "STATEMENT" + ], + "nextStatement": "STATEMENT", + "colour": 195, + "tooltip": "Use to set or check the value of a relationship.", + "helpUrl": "/docs/blocks/relationship_selector/" +}, +{ + "type": "relationship_selector7", + "message0": "%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15", + "args0": [ + { + "type": "field_label_serializable", + "name": "prefix1", + "text": "prefix1" + }, + { + "type": "input_value", + "name": "parameter1", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix2", + "text": "prefix2" + }, + { + "type": "input_value", + "name": "parameter2", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix3", + "text": "prefix3" + }, + { + "type": "input_value", + "name": "parameter3", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix4", + "text": "prefix4" + }, + { + "type": "input_value", + "name": "parameter4", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix5", + "text": "prefix5" + }, + { + "type": "input_value", + "name": "parameter5", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix6", + "text": "prefix6" + }, + { + "type": "input_value", + "name": "parameter6", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix7", + "text": "prefix7" + }, + { + "type": "input_value", + "name": "parameter7", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "postfix", + "text": "postfix" + } + ], + "inputsInline": true, + "previousStatement": [ + "OUTER", + "STATEMENT" + ], + "nextStatement": "STATEMENT", + "colour": 195, + "tooltip": "Use to set or check the value of a relationship.", + "helpUrl": "/docs/blocks/relationship_selector/" +}, +{ + "type": "relationship_selector8", + "message0": "%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15 %16 %17", + "args0": [ + { + "type": "field_label_serializable", + "name": "prefix1", + "text": "prefix1" + }, + { + "type": "input_value", + "name": "parameter1", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix2", + "text": "prefix2" + }, + { + "type": "input_value", + "name": "parameter2", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix3", + "text": "prefix3" + }, + { + "type": "input_value", + "name": "parameter3", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix4", + "text": "prefix4" + }, + { + "type": "input_value", + "name": "parameter4", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix5", + "text": "prefix5" + }, + { + "type": "input_value", + "name": "parameter5", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix6", + "text": "prefix6" + }, + { + "type": "input_value", + "name": "parameter6", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix7", + "text": "prefix7" + }, + { + "type": "input_value", + "name": "parameter7", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix8", + "text": "prefix8" + }, + { + "type": "input_value", + "name": "parameter8", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "postfix", + "text": "postfix" + } + ], + "inputsInline": true, + "previousStatement": [ + "OUTER", + "STATEMENT" + ], + "nextStatement": "STATEMENT", + "colour": 195, + "tooltip": "Use to set or check the value of a relationship.", + "helpUrl": "/docs/blocks/relationship_selector/" +}, +{ + "type": "relationship_selector9", + "message0": "%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15 %16 %17 %18 %19", + "args0": [ + { + "type": "field_label_serializable", + "name": "prefix1", + "text": "prefix1" + }, + { + "type": "input_value", + "name": "parameter1", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix2", + "text": "prefix2" + }, + { + "type": "input_value", + "name": "parameter2", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix3", + "text": "prefix3" + }, + { + "type": "input_value", + "name": "parameter3", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix4", + "text": "prefix4" + }, + { + "type": "input_value", + "name": "parameter4", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix5", + "text": "prefix5" + }, + { + "type": "input_value", + "name": "parameter5", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix6", + "text": "prefix6" + }, + { + "type": "input_value", + "name": "parameter6", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix7", + "text": "prefix7" + }, + { + "type": "input_value", + "name": "parameter7", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix8", + "text": "prefix8" + }, + { + "type": "input_value", + "name": "parameter8", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix9", + "text": "prefix9" + }, + { + "type": "input_value", + "name": "parameter9", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "postfix", + "text": "postfix" + } + ], + "inputsInline": true, + "previousStatement": [ + "OUTER", + "STATEMENT" + ], + "nextStatement": "STATEMENT", + "colour": 195, + "tooltip": "Use to set or check the value of a relationship.", + "helpUrl": "/docs/blocks/relationship_selector/" +}, +{ + "type": "relationship_selector10", + "message0": "%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15 %16 %17 %18 %19 %20 %21", + "args0": [ + { + "type": "field_label_serializable", + "name": "prefix1", + "text": "prefix1" + }, + { + "type": "input_value", + "name": "parameter1", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix2", + "text": "prefix2" + }, + { + "type": "input_value", + "name": "parameter2", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix3", + "text": "prefix3" + }, + { + "type": "input_value", + "name": "parameter3", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix4", + "text": "prefix4" + }, + { + "type": "input_value", + "name": "parameter4", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix5", + "text": "prefix5" + }, + { + "type": "input_value", + "name": "parameter5", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix6", + "text": "prefix6" + }, + { + "type": "input_value", + "name": "parameter6", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix7", + "text": "prefix7" + }, + { + "type": "input_value", + "name": "parameter7", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix8", + "text": "prefix8" + }, + { + "type": "input_value", + "name": "parameter8", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix9", + "text": "prefix9" + }, + { + "type": "input_value", + "name": "parameter9", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "prefix10", + "text": "prefix10" + }, + { + "type": "input_value", + "name": "parameter10", + "check": [ + "VARIABLE", + "SOMETHING" + ] + }, + { + "type": "field_label_serializable", + "name": "postfix", + "text": "postfix" + } + ], + "inputsInline": true, + "previousStatement": [ + "OUTER", + "STATEMENT" + ], + "nextStatement": "STATEMENT", + "colour": 195, + "tooltip": "Use to set or check the value of a relationship.", + "helpUrl": "/docs/blocks/relationship_selector/" }] \ No newline at end of file diff --git a/blawx/util/blawx_block_library.xml b/blawx/util/blawx_block_library.xml index ef043ed7..f1c46c1f 100644 --- a/blawx/util/blawx_block_library.xml +++ b/blawx/util/blawx_block_library.xml @@ -9522,4 +9522,2293 @@ 330 + + + relationship_declaration + AUTO + BOTH + + + LEFT + + + relationship_name + relationship_name + + + is a relationship between + + + + arity + 3 + 3 + 4 + 4 + 5 + 5 + 6 + 6 + 7 + 7 + 8 + 8 + 9 + 9 + 10 + 10 + + + objects or values described as + + + + + + + + + + + LEFT + + + + prefix1 + + + + type1 + option + OPTIONNAME + option + OPTIONNAME + option + OPTIONNAME + + + + prefix2 + + + + type2 + option + OPTIONNAME + option + OPTIONNAME + option + OPTIONNAME + + + + prefix3 + + + + type3 + option + OPTIONNAME + option + OPTIONNAME + option + OPTIONNAME + + + + postfix + + + + + + + + + + + + + + + + + + + + + Use to declare a relationship between 3 or more objects or values. + + + + + /docs/blocks/new_relationship/ + + + + + + + + + OUTER + + + + + STATEMENT + + + + + + + + STATEMENT + + + + + + 30 + + + + + relationship_selector + INT + BOTH + + + first_element + LEFT + + + prefix1 + prefix1 + + + + + + + + second_element + LEFT + + + prefix2 + prefix2 + + + + + + + + third_element + LEFT + + + prefix3 + prefix3 + + + + + + + + LEFT + + + postfix + postfix + + + + + + + + + + + + + Use to set or check the value of a relationship. + + + + + /docs/blocks/relationship_selector/ + + + + + + + + + OUTER + + + + + STATEMENT + + + + + + + + STATEMENT + + + + + + 150 + + + + + relationship_ddeclaration + AUTO + BOTH + + + LEFT + + + relationship_name + relationship_name + + + is a relationship between + + + + arity + 3 + 3 + 4 + 4 + 5 + 5 + 6 + 6 + 7 + 7 + 8 + 8 + 9 + 9 + 10 + 10 + + + objects or values described as + + + + + + + + + + + LEFT + + + + prefix1 + + + + type1 + option + OPTIONNAME + option + OPTIONNAME + option + OPTIONNAME + + + + prefix2 + + + + type2 + option + OPTIONNAME + option + OPTIONNAME + option + OPTIONNAME + + + + prefix3 + + + + type3 + option + OPTIONNAME + option + OPTIONNAME + option + OPTIONNAME + + + + postfix + + + + + + + + + + + + + + + + + + + + + Use to declare a relationship between 3 or more objects or values. + + + + + /docs/blocks/new_relationship/ + + + + + + + + + OUTER + + + + + STATEMENT + + + + + + + + STATEMENT + + + + + + 30 + + + + + relationship_selector3 + INT + BOTH + + + parameter1 + LEFT + + + prefix1 + prefix1 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter2 + LEFT + + + prefix2 + prefix2 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter3 + LEFT + + + prefix3 + prefix3 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + LEFT + + + postfix + postfix + + + + + + + + + + + + + Use to set or check the value of a relationship. + + + + + /docs/blocks/relationship_selector/ + + + + + + + + + OUTER + + + + + STATEMENT + + + + + + + + STATEMENT + + + + + + 195 + + + + + relationship_selector4 + INT + BOTH + + + parameter1 + LEFT + + + prefix1 + prefix1 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter2 + LEFT + + + prefix2 + prefix2 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter3 + LEFT + + + prefix3 + prefix3 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter4 + LEFT + + + prefix4 + prefix4 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + LEFT + + + postfix + postfix + + + + + + + + + + + + + + + Use to set or check the value of a relationship. + + + + + /docs/blocks/relationship_selector/ + + + + + + + + + OUTER + + + + + STATEMENT + + + + + + + + STATEMENT + + + + + + 195 + + + + + relationship_selector5 + INT + BOTH + + + parameter1 + LEFT + + + prefix1 + prefix1 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter2 + LEFT + + + prefix2 + prefix2 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter3 + LEFT + + + prefix3 + prefix3 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter4 + LEFT + + + prefix4 + prefix4 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter5 + LEFT + + + prefix5 + prefix5 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + LEFT + + + postfix + postfix + + + + + + + + + + + + + + + + + Use to set or check the value of a relationship. + + + + + /docs/blocks/relationship_selector/ + + + + + + + + + OUTER + + + + + STATEMENT + + + + + + + + STATEMENT + + + + + + 195 + + + + + relationship_selector6 + INT + BOTH + + + parameter1 + LEFT + + + prefix1 + prefix1 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter2 + LEFT + + + prefix2 + prefix2 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter3 + LEFT + + + prefix3 + prefix3 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter4 + LEFT + + + prefix4 + prefix4 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter5 + LEFT + + + prefix5 + prefix5 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter6 + LEFT + + + prefix6 + prefix6 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + LEFT + + + postfix + postfix + + + + + + + + + + + + + + + + + + + Use to set or check the value of a relationship. + + + + + /docs/blocks/relationship_selector/ + + + + + + + + + OUTER + + + + + STATEMENT + + + + + + + + STATEMENT + + + + + + 195 + + + + + relationship_selector7 + INT + BOTH + + + parameter1 + LEFT + + + prefix1 + prefix1 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter2 + LEFT + + + prefix2 + prefix2 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter3 + LEFT + + + prefix3 + prefix3 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter4 + LEFT + + + prefix4 + prefix4 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter5 + LEFT + + + prefix5 + prefix5 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter6 + LEFT + + + prefix6 + prefix6 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter7 + LEFT + + + prefix7 + prefix7 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + LEFT + + + postfix + postfix + + + + + + + + + + + + + + + + + + + + + Use to set or check the value of a relationship. + + + + + /docs/blocks/relationship_selector/ + + + + + + + + + OUTER + + + + + STATEMENT + + + + + + + + STATEMENT + + + + + + 195 + + + + + relationship_selector8 + INT + BOTH + + + parameter1 + LEFT + + + prefix1 + prefix1 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter2 + LEFT + + + prefix2 + prefix2 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter3 + LEFT + + + prefix3 + prefix3 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter4 + LEFT + + + prefix4 + prefix4 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter5 + LEFT + + + prefix5 + prefix5 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter6 + LEFT + + + prefix6 + prefix6 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter7 + LEFT + + + prefix7 + prefix7 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter8 + LEFT + + + prefix8 + prefix8 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + LEFT + + + postfix + postfix + + + + + + + + + + + + + + + + + + + + + + + Use to set or check the value of a relationship. + + + + + /docs/blocks/relationship_selector/ + + + + + + + + + OUTER + + + + + STATEMENT + + + + + + + + STATEMENT + + + + + + 195 + + + + + relationship_selector9 + INT + BOTH + + + parameter1 + LEFT + + + prefix1 + prefix1 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter2 + LEFT + + + prefix2 + prefix2 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter3 + LEFT + + + prefix3 + prefix3 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter4 + LEFT + + + prefix4 + prefix4 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter5 + LEFT + + + prefix5 + prefix5 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter6 + LEFT + + + prefix6 + prefix6 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter7 + LEFT + + + prefix7 + prefix7 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter8 + LEFT + + + prefix8 + prefix8 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter9 + LEFT + + + prefix9 + prefix9 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + LEFT + + + postfix + postfix + + + + + + + + + + + + + + + + + + + + + + + + + Use to set or check the value of a relationship. + + + + + /docs/blocks/relationship_selector/ + + + + + + + + + OUTER + + + + + STATEMENT + + + + + + + + STATEMENT + + + + + + 195 + + + + + relationship_selector10 + INT + BOTH + + + parameter1 + LEFT + + + prefix1 + prefix1 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter2 + LEFT + + + prefix2 + prefix2 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter3 + LEFT + + + prefix3 + prefix3 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter4 + LEFT + + + prefix4 + prefix4 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter5 + LEFT + + + prefix5 + prefix5 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter6 + LEFT + + + prefix6 + prefix6 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter7 + LEFT + + + prefix7 + prefix7 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter8 + LEFT + + + prefix8 + prefix8 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter9 + LEFT + + + prefix9 + prefix9 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + parameter10 + LEFT + + + prefix10 + prefix10 + + + + + + + + + VARIABLE + + + + + SOMETHING + + + + + + + LEFT + + + postfix + postfix + + + + + + + + + + + + + + + + + + + + + + + + + + + Use to set or check the value of a relationship. + + + + + /docs/blocks/relationship_selector/ + + + + + + + + + OUTER + + + + + STATEMENT + + + + + + + + STATEMENT + + + + + + 195 + + \ No newline at end of file