From 694441d9a90c573045aef6fb7189b882a229b57b Mon Sep 17 00:00:00 2001 From: Gauntlet173 Date: Mon, 24 Apr 2023 14:50:10 -0600 Subject: [PATCH 01/16] add relationship declaration, known relationships --- CHANGELOG.md | 21 + blawx/static/blawx/attributes.js | 2 - blawx/static/blawx/blawx-blocks.js | 1277 ++++++++++++- blawx/static/blawx/drawers.js | 53 + blawx/static/blawx/mutators.js | 24 + blawx/static/blawx/scasp_generator.js | 115 ++ blawx/templates/blawx/blawx.html | 4 + blawx/templates/blawx/test.html | 4 + blawx/util/blawx_block_definitions.json | 1151 ++++++++++++ blawx/util/blawx_block_library.xml | 2289 +++++++++++++++++++++++ 10 files changed, 4936 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4057012b..424c91b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,27 @@ 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. +## ARITY_3PLUS + +### Added +* Relationship Declaration Block +* Relationship Selector Blocks +* Known Relationship Drawer + +### Changed + +### Removed + +### Fixed + +### TODO +* Code generation for relationship declaration block. +* Code gen for relationship selector blocks +* Scenario editor facts and explanations now use relationships +* Ontology endpoint includes information on declared relationships and associated NLG + + + ## [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/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..dfa2b41d 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": "param3ter5", + "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/drawers.js b/blawx/static/blawx/drawers.js index 64c65b81..7937ded1 100644 --- a/blawx/static/blawx/drawers.js +++ b/blawx/static/blawx/drawers.js @@ -64,6 +64,59 @@ 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'); + console.log("Creating known relationship for " + relationship_name + " of arity " + arity) + 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/mutators.js b/blawx/static/blawx/mutators.js index 82017110..11c630c9 100644 --- a/blawx/static/blawx/mutators.js +++ b/blawx/static/blawx/mutators.js @@ -115,6 +115,30 @@ Blockly.Extensions.register('changeAttributeDisplayText', function() { }); }); +RELATIONSHIP_SELECTOR_MUTATOR_MIXIN = { + mutationToDom: function() { + var container = document.createElement('mutation'); + var arity = parseInt(this.type.slice(-1)); + container.setAttribute('arity',arity); + container.setAttribute('relationship_name',this.relationship_name); + for (var i=1; i<= arity; i++) { + container.setAttribute('type'+i, this['type'+i]); + } + return container; + }, + domToMutation: function(xmlElement) { + var arity = parseInt(xmlElement.getAttribute('arity')); + this.relationship_name = xmlElement.getAttribute('relationship_name'); + for (var i=1; i<=arity; i++) { + this['type'+i] = xmlElement.getAttribute('type'+i); + this.getInput("parameter"+i).connection.setCheck([blawxTypeToBlocklyType(this['type'+i]),'VARIABLE']) + } + } +} + +Blockly.Extensions.registerMutator('relationship_selector_mutator', RELATIONSHIP_SELECTOR_MUTATOR_MIXIN); + + ATTRIBUTE_SELECTOR_MUTATOR_MIXIN = { mutationToDom: function() { // console.log("Saving : " + this.blawxAttributeName + ", " + this.blawxAttributeType + ", " + this.blawxAttributeOrder) diff --git a/blawx/static/blawx/scasp_generator.js b/blawx/static/blawx/scasp_generator.js index 16fc48da..43f2c370 100644 --- a/blawx/static/blawx/scasp_generator.js +++ b/blawx/static/blawx/scasp_generator.js @@ -1237,6 +1237,121 @@ sCASP['time_from_ts'] = function(block) { return [code, sCASP.ORDER_ATOMIC]; }; +sCASP['relationship_declaration'] = function(block) { + var text_relationship_name = block.getFieldValue('relationship_name'); + var number_arity = block.getFieldValue('arity'); + var text_prefix1 = block.getFieldValue('prefix1'); + var dropdown_type1 = block.getFieldValue('type1'); + var text_prefix2 = block.getFieldValue('prefix2'); + var dropdown_type2 = block.getFieldValue('type2'); + var text_prefix3 = block.getFieldValue('prefix3'); + var dropdown_type3 = block.getFieldValue('type3'); + var text_postfix = block.getFieldValue('postfix'); + // TODO: Assemble JavaScript into code variable. + var code = '...;\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); + // TODO: Assemble JavaScript into code variable. + var code = '...;\n'; + 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); + // TODO: Assemble JavaScript into code variable. + var code = '...;\n'; + 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); + // TODO: Assemble JavaScript into code variable. + var code = '...;\n'; + 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_param3ter5 = sCASP.valueToCode(block, 'param3ter5', sCASP.ORDER_ATOMIC); + var value_parameter6 = sCASP.valueToCode(block, 'parameter6', sCASP.ORDER_ATOMIC); + // TODO: Assemble JavaScript into code variable. + var code = '...;\n'; + 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); + // TODO: Assemble JavaScript into code variable. + var code = '...;\n'; + 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); + // TODO: Assemble JavaScript into code variable. + var code = '...;\n'; + 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); + // TODO: Assemble JavaScript into code variable. + var code = '...;\n'; + 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); + // TODO: Assemble JavaScript into code variable. + var code = '...;\n'; + 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/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..afddac7e 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": "param3ter5", + "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..8791722b 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 + + + + + + + param3ter5 + 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 From 4c2b12abd525316d1646238cad1d9cefe4cae2c0 Mon Sep 17 00:00:00 2001 From: Gauntlet173 Date: Mon, 24 Apr 2023 19:51:20 -0600 Subject: [PATCH 02/16] add code generation for relationships --- CHANGELOG.md | 3 +- blawx/static/blawx/blawx-blocks.js | 2 +- blawx/static/blawx/drawers.js | 4 - blawx/static/blawx/mutators.js | 6 +- blawx/static/blawx/scasp_generator.js | 123 +++++++++++++++++------- blawx/util/blawx_block_definitions.json | 2 +- blawx/util/blawx_block_library.xml | 2 +- 7 files changed, 94 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 424c91b3..549a7d74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,10 +19,9 @@ and breaking changes will not necessarily result in changes to the main version ### Removed ### Fixed +* Problems with natural language generation for non-boolean attributes in test editor explanations ### TODO -* Code generation for relationship declaration block. -* Code gen for relationship selector blocks * Scenario editor facts and explanations now use relationships * Ontology endpoint includes information on declared relationships and associated NLG diff --git a/blawx/static/blawx/blawx-blocks.js b/blawx/static/blawx/blawx-blocks.js index dfa2b41d..c3aa488d 100644 --- a/blawx/static/blawx/blawx-blocks.js +++ b/blawx/static/blawx/blawx-blocks.js @@ -4562,7 +4562,7 @@ scasp_blockset = [{ }, { "type": "input_value", - "name": "param3ter5", + "name": "parameter5", "check": [ "VARIABLE", "SOMETHING" diff --git a/blawx/static/blawx/drawers.js b/blawx/static/blawx/drawers.js index 7937ded1..e5747e81 100644 --- a/blawx/static/blawx/drawers.js +++ b/blawx/static/blawx/drawers.js @@ -80,18 +80,14 @@ knownRelationshipsCallback = function(workspace) { if (blockList[i].type == "relationship_declaration") { var arity = parseInt(blockList[i].getFieldValue('relationship_arity')); var relationship_name = blockList[i].getFieldValue('relationship_name'); - console.log("Creating known relationship for " + relationship_name + " of arity " + arity) var blocktype = "relationship_selector" + arity; var blockText = "" // Add the mutator, which should include the name and the types blockText += " 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; }; @@ -1256,8 +1315,7 @@ 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); - // TODO: Assemble JavaScript into code variable. - var code = '...;\n'; + var code = this.relationship_name + "(" + value_parameter1 + "," + value_parameter2 + "," + value_parameter3 + ")"; return code; }; @@ -1266,8 +1324,7 @@ sCASP['relationship_selector3'] = function(block) { 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); - // TODO: Assemble JavaScript into code variable. - var code = '...;\n'; + var code = this.relationship_name + "(" + value_parameter1 + "," + value_parameter2 + "," + value_parameter3 + "," + value_parameter4 + ")"; return code; }; @@ -1277,8 +1334,7 @@ sCASP['relationship_selector3'] = function(block) { 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); - // TODO: Assemble JavaScript into code variable. - var code = '...;\n'; + var code = this.relationship_name + "(" + value_parameter1 + "," + value_parameter2 + "," + value_parameter3 + "," + value_parameter4 + "," + value_parameter5 + ")"; return code; }; @@ -1287,10 +1343,9 @@ sCASP['relationship_selector3'] = function(block) { 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_param3ter5 = sCASP.valueToCode(block, 'param3ter5', sCASP.ORDER_ATOMIC); + var value_parameter5 = sCASP.valueToCode(block, 'parameter5', sCASP.ORDER_ATOMIC); var value_parameter6 = sCASP.valueToCode(block, 'parameter6', sCASP.ORDER_ATOMIC); - // TODO: Assemble JavaScript into code variable. - var code = '...;\n'; + var code = this.relationship_name + "(" + value_parameter1 + "," + value_parameter2 + "," + value_parameter3 + "," + value_parameter4 + "," + value_parameter5 + "," + value_parameter6 + ")"; return code; }; @@ -1302,8 +1357,7 @@ sCASP['relationship_selector3'] = function(block) { 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); - // TODO: Assemble JavaScript into code variable. - var code = '...;\n'; + var code = this.relationship_name + "(" + value_parameter1 + "," + value_parameter2 + "," + value_parameter3 + "," + value_parameter4 + "," + value_parameter5 + "," + value_parameter6 + "," + value_parameter7 + ")"; return code; }; @@ -1316,8 +1370,7 @@ sCASP['relationship_selector3'] = function(block) { 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); - // TODO: Assemble JavaScript into code variable. - var code = '...;\n'; + var code = this.relationship_name + "(" + value_parameter1 + "," + value_parameter2 + "," + value_parameter3 + "," + value_parameter4 + "," + value_parameter5 + "," + value_parameter6 + "," + value_parameter7 + "," + value_parameter8 + ")"; return code; }; @@ -1331,8 +1384,7 @@ sCASP['relationship_selector3'] = function(block) { 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); - // TODO: Assemble JavaScript into code variable. - var code = '...;\n'; + 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; }; @@ -1347,8 +1399,7 @@ sCASP['relationship_selector3'] = function(block) { 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); - // TODO: Assemble JavaScript into code variable. - var code = '...;\n'; + 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; }; diff --git a/blawx/util/blawx_block_definitions.json b/blawx/util/blawx_block_definitions.json index afddac7e..2dc8d288 100644 --- a/blawx/util/blawx_block_definitions.json +++ b/blawx/util/blawx_block_definitions.json @@ -4562,7 +4562,7 @@ }, { "type": "input_value", - "name": "param3ter5", + "name": "parameter5", "check": [ "VARIABLE", "SOMETHING" diff --git a/blawx/util/blawx_block_library.xml b/blawx/util/blawx_block_library.xml index 8791722b..f1c46c1f 100644 --- a/blawx/util/blawx_block_library.xml +++ b/blawx/util/blawx_block_library.xml @@ -10532,7 +10532,7 @@ - param3ter5 + parameter5 LEFT From 569211b6ed68664c14741be8cdc39fdd53fefd5b Mon Sep 17 00:00:00 2001 From: Gauntlet173 Date: Mon, 24 Apr 2023 21:00:13 -0600 Subject: [PATCH 03/16] add relationships to onto output --- blawx/reasoner.py | 128 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 127 insertions(+), 1 deletion(-) diff --git a/blawx/reasoner.py b/blawx/reasoner.py index 93190df4..1a582a87 100644 --- a/blawx/reasoner.py +++ b/blawx/reasoner.py @@ -662,6 +662,132 @@ 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 + transcript.write(str(query1_answer) + '\n') object_query_answers = [] for cat in query1_answers: @@ -753,7 +879,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, "Objects": object_query_answers, "Values": value_query_answers, "Transcript": transcript_output } @api_view(['GET']) @authentication_classes([SessionAuthentication]) From d576b505d574711d5afe5eb8f9e0b89611f732df Mon Sep 17 00:00:00 2001 From: Gauntlet173 Date: Tue, 25 Apr 2023 10:36:22 -0600 Subject: [PATCH 04/16] get onto endpoint to report relationship nlg --- blawx/reasoner.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/blawx/reasoner.py b/blawx/reasoner.py index 1a582a87..c50087a7 100644 --- a/blawx/reasoner.py +++ b/blawx/reasoner.py @@ -788,6 +788,30 @@ def get_ontology_internal(ruledoc,test_name): 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 += 'Parameter'+str(param) + "," + param += 1 + query += "Postfix),Human)." + print("Query: " + query) + 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['Parameter'+str(param_count)] = relnlg['Variables']['Parameter'+str(param_count)] + param_count += 1 + relationship_nlg.append(new_nlg) + 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: @@ -879,7 +903,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, "Relationships": relationship_answers, "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, "Transcript": transcript_output } @api_view(['GET']) @authentication_classes([SessionAuthentication]) From 8824cb64f8f5886b6007b73548369799649aa7a6 Mon Sep 17 00:00:00 2001 From: Gauntlet173 Date: Tue, 25 Apr 2023 10:48:29 -0600 Subject: [PATCH 05/16] add existing relations to onto output --- blawx/reasoner.py | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/blawx/reasoner.py b/blawx/reasoner.py index c50087a7..b1f97a99 100644 --- a/blawx/reasoner.py +++ b/blawx/reasoner.py @@ -798,7 +798,6 @@ def get_ontology_internal(ruledoc,test_name): query += 'Parameter'+str(param) + "," param += 1 query += "Postfix),Human)." - print("Query: " + query) rel_nlg_query_response = swipl_thread.query(query) rel_nlg_answers = generate_answers(rel_nlg_query_response) for relnlg in rel_nlg_answers: @@ -812,6 +811,32 @@ def get_ontology_internal(ruledoc,test_name): 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)." + print("Query: " + query) + 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: @@ -903,7 +928,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, "Relationships": relationship_answers, "RelationshipNLG": relationship_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]) From 5b94187323ebc6576e95046a8d16c90a2b223bd8 Mon Sep 17 00:00:00 2001 From: Gauntlet173 Date: Tue, 25 Apr 2023 15:04:19 -0600 Subject: [PATCH 06/16] update json format for reasoner API --- blawx/reasoner.py | 372 ++++++++++++++++++++++++++++------------------ 1 file changed, 224 insertions(+), 148 deletions(-) diff --git a/blawx/reasoner.py b/blawx/reasoner.py index b1f97a99..6e0af0b4 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)) @@ -823,7 +900,6 @@ def get_ontology_internal(ruledoc,test_name): query += "," param += 1 query += "),Human)." - print("Query: " + query) rel_fact_query_response = swipl_thread.query(query) rel_fact_answers = generate_answers(rel_fact_query_response) for relfact in rel_fact_answers: @@ -1089,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) @@ -1279,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. From 10308267f751ba0203858d5581da6a85aaa28f81 Mon Sep 17 00:00:00 2001 From: Gauntlet173 Date: Tue, 25 Apr 2023 15:16:11 -0600 Subject: [PATCH 07/16] updates to changelog and version --- CHANGELOG.md | 15 ++++++++++----- blawx/settings.py | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 549a7d74..2b819478 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,10 @@ 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. -## ARITY_3PLUS +## [v1.6.1-alpha](https://github.com/Lexpedite/blawx/releases/tag/v1.6.1-alpha) 2023-04-?? + +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 @@ -15,6 +18,8 @@ and breaking changes will not necessarily result in changes to the main version * Known Relationship Drawer ### 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 ### Removed @@ -22,10 +27,10 @@ and breaking changes will not necessarily result in changes to the main version * Problems with natural language generation for non-boolean attributes in test editor explanations ### TODO -* Scenario editor facts and explanations now use relationships -* Ontology endpoint includes information on declared relationships and associated NLG - - +* Scenario editor + * Scenario editor will let you add relationship statements to your facts + * Scenario editor will correctly encode relationship statements + * Scenario editor will correctly display relationship statements in explanations ## [v1.6.0-alpha](https://github.com/Lexpedite/blawx/releases/tag/v1.6.0-alpha) 2023-04-11 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'. From 61080665aa430cf56b1974fb5d35c72aa00888a1 Mon Sep 17 00:00:00 2001 From: Gauntlet173 Date: Tue, 25 Apr 2023 18:29:39 -0600 Subject: [PATCH 08/16] initial documentation for new blocks --- CHANGELOG.md | 9 +++++ .../blocks/categories/new_relationship.yaml | 35 ++++++++++++++++++ .../categories/relationship_selector.yaml | 26 +++++++++++++ .../docs/images/blocks/new_relationship.png | Bin 0 -> 8444 bytes .../images/blocks/relationship_selector.png | Bin 0 -> 3876 bytes 5 files changed, 70 insertions(+) create mode 100644 blawx/fixtures/docs/blocks/categories/new_relationship.yaml create mode 100644 blawx/fixtures/docs/blocks/categories/relationship_selector.yaml create mode 100644 blawx/static/blawx/docs/images/blocks/new_relationship.png create mode 100644 blawx/static/blawx/docs/images/blocks/relationship_selector.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b819478..51d97e4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,15 @@ a statement that is true (or not) about 3 or more objects or values. * Scenario editor will let you add relationship statements to your facts * Scenario editor will correctly encode relationship statements * Scenario editor will correctly display relationship statements in explanations +* Documentation + * Relationship Declaration Block Page + * Relationship Selector Page + * Categories & Attributes Page + * Code Editor Page + * Web API Page +* Examples + * Update existing examples + * Probably doesn't need new examples. ## [v1.6.0-alpha](https://github.com/Lexpedite/blawx/releases/tag/v1.6.0-alpha) 2023-04-11 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/static/blawx/docs/images/blocks/new_relationship.png b/blawx/static/blawx/docs/images/blocks/new_relationship.png new file mode 100644 index 0000000000000000000000000000000000000000..1b1856084ca693ffbe1d42ea35528acc535784b1 GIT binary patch literal 8444 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..ecfe90a3b356502a792eab48996941e7127006b5 GIT binary patch literal 3876 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 Date: Tue, 25 Apr 2023 18:31:13 -0600 Subject: [PATCH 09/16] add new pages to doc index --- blawx/templates/blawx/docs.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/blawx/templates/blawx/docs.html b/blawx/templates/blawx/docs.html index f9100b6a..56153b6b 100644 --- a/blawx/templates/blawx/docs.html +++ b/blawx/templates/blawx/docs.html @@ -269,6 +269,8 @@
  • New Category
  • New Attribute
  • Attribute Selector
  • +
  • New Relationship
  • +
  • Relationship Selector
  • From 0f6d52d6495188d7e9310f5c78137c6791c65b55 Mon Sep 17 00:00:00 2001 From: Gauntlet173 Date: Tue, 25 Apr 2023 18:43:45 -0600 Subject: [PATCH 10/16] adding relationships to categories docs --- blawx/fixtures/docs/features/categories.yaml | 40 +++++++++++++------- blawx/templates/blawx/docs.html | 2 +- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/blawx/fixtures/docs/features/categories.yaml b/blawx/fixtures/docs/features/categories.yaml index e15310af..e02eeb87 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/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/templates/blawx/docs.html b/blawx/templates/blawx/docs.html index 56153b6b..2e6ef10c 100644 --- a/blawx/templates/blawx/docs.html +++ b/blawx/templates/blawx/docs.html @@ -161,7 +161,7 @@
      -
    • Categories and Attributes
    • +
    • Categories, Attributes, Relationships
    • Rules
    • Facts and Assumptions
    • Questions
    • From 261ce1d8daa3ab4ae70a67614e515d04a0fdce93 Mon Sep 17 00:00:00 2001 From: Gauntlet173 Date: Tue, 25 Apr 2023 18:55:55 -0600 Subject: [PATCH 11/16] updates to web api documentation --- CHANGELOG.md | 7 ++---- blawx/fixtures/docs/components/web-api.yaml | 27 +++++++++++++++++---- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51d97e4d..f1460d1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,10 +16,12 @@ a statement that is true (or not) about 3 or more objects or values. * 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 +* Associated documentation ### Removed @@ -32,14 +34,9 @@ a statement that is true (or not) about 3 or more objects or values. * Scenario editor will correctly encode relationship statements * Scenario editor will correctly display relationship statements in explanations * Documentation - * Relationship Declaration Block Page - * Relationship Selector Page - * Categories & Attributes Page * Code Editor Page - * Web API Page * Examples * Update existing examples - * Probably doesn't need new examples. ## [v1.6.0-alpha](https://github.com/Lexpedite/blawx/releases/tag/v1.6.0-alpha) 2023-04-11 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". From 4fc6146636d263a0ae21d1ad661611339b85c3e4 Mon Sep 17 00:00:00 2001 From: Gauntlet173 Date: Wed, 26 Apr 2023 15:36:48 -0600 Subject: [PATCH 12/16] wip adding relationship to scenario editor --- CHANGELOG.md | 9 +- blawx/reasoner.py | 4 +- blawx/templates/blawx/scenario_editor.html | 184 +++++++++++++++------ 3 files changed, 146 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1460d1b..b37fbf95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,9 +30,12 @@ a statement that is true (or not) about 3 or more objects or values. ### TODO * Scenario editor - * Scenario editor will let you add relationship statements to your facts - * Scenario editor will correctly encode relationship statements - * Scenario editor will correctly display relationship statements in explanations + * Displays variables properly in fact display + * Displays data types properly in fact display + * New Relationship Forms + * Saving + * Deleting + * Check facts work when sent to reasoner * Documentation * Code Editor Page * Examples diff --git a/blawx/reasoner.py b/blawx/reasoner.py index 6e0af0b4..419f522a 100644 --- a/blawx/reasoner.py +++ b/blawx/reasoner.py @@ -872,7 +872,7 @@ def get_ontology_internal(ruledoc,test_name): parameters = len(a)-1 param = 1 while param <= parameters: - query += 'Parameter'+str(param) + "," + query += 'Prefix'+str(param) + "," param += 1 query += "Postfix),Human)." rel_nlg_query_response = swipl_thread.query(query) @@ -881,7 +881,7 @@ def get_ontology_internal(ruledoc,test_name): new_nlg = {"Relationship": a['Relationship'], "Postfix": relnlg['Variables']['Postfix']} param_count = 1 while param_count <= parameters: - new_nlg['Parameter'+str(param_count)] = relnlg['Variables']['Parameter'+str(param_count)] + new_nlg['Prefix'+str(param_count)] = relnlg['Variables']['Prefix'+str(param_count)] param_count += 1 relationship_nlg.append(new_nlg) except PrologError as err: diff --git a/blawx/templates/blawx/scenario_editor.html b/blawx/templates/blawx/scenario_editor.html index 1a5c39b7..0055e1d0 100644 --- a/blawx/templates/blawx/scenario_editor.html +++ b/blawx/templates/blawx/scenario_editor.html @@ -703,7 +703,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 +727,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 +746,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 +776,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 +798,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); + } } @@ -1018,57 +1046,84 @@
      Response
      } } output_html += '
      '; - output_html += ''; + } + output_html += '
    '; + output_html += '
    '; + output_html += ''; output_html += ''; @@ -1398,6 +1453,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 +1506,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 +1543,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 +1620,26 @@
    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; + } + } + for (var i=1; i <= arity; i++) { + output_html += " " + prefixes[i] + " " + new_fact_data['facts'][f]['parameter'+i]; + } + 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 From 30d7af73f2df2726e73b007b03b0462203119159 Mon Sep 17 00:00:00 2001 From: Gauntlet173 Date: Wed, 26 Apr 2023 17:57:46 -0600 Subject: [PATCH 13/16] relationship support in scenario editor facts --- CHANGELOG.md | 10 +- blawx/templates/blawx/scenario_editor.html | 157 ++++++++++++++++++++- 2 files changed, 157 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b37fbf95..4e8f0929 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,10 +21,10 @@ a statement that is true (or not) about 3 or more objects or values. ### 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. * Associated documentation -### Removed - ### Fixed * Problems with natural language generation for non-boolean attributes in test editor explanations @@ -32,12 +32,6 @@ a statement that is true (or not) about 3 or more objects or values. * Scenario editor * Displays variables properly in fact display * Displays data types properly in fact display - * New Relationship Forms - * Saving - * Deleting - * Check facts work when sent to reasoner -* Documentation - * Code Editor Page * Examples * Update existing examples diff --git a/blawx/templates/blawx/scenario_editor.html b/blawx/templates/blawx/scenario_editor.html index 0055e1d0..09dbd52c 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
    @@ -868,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; @@ -1045,6 +1049,59 @@
    Response
    output_html += '
    '; } } + for(var r = 0; r < ontology['Relationships'].length; r++) { + if (!hidden_by_view.includes('view_rel_' + relationship_name)) { + var relationship_name = ontology['Relationships'][r]['Relationship'] + var arity = Object.keys(ontology['Relationships'][r]).length-1; + // Get type info + var types = {}; + for (var t = 1; t <= arity; t++) { + types[t] = ontology['Relationships'][r]['Parameter'+t]; + } + // Get NLG info + var postfix = ""; + var prefixes = []; + for (var n = 0; n < ontology['RelationshipNLG'].length; n++) { + if (relationship_name == ontology['RelationshipNLG'][n]['Relationship']) { + postfix = ontology['RelationshipNLG'][n]['Postfix']; + for (var p = 1; p <= arity; p++) { + prefixes[p] = ontology['RelationshipNLG'][n]['Prefix'+p] + } + } + break; + } + // Truth Type + output_html += '
    '; + output_html += '
    '; + output_html += 'It is'; + + output_html += '
    '; + // Parameters + for (var p = 1; p <= arity; p++) { + if (prefixes[p] != "") { + output_html += '' + prefixes[p] + ''; + } + output_html += generate_field_control(relationship_name,p,types[p]); + } + // Postfix + if (postfix != "") { + output_html += ''+ postfix + ''; + } + // Save and Cancel Buttons + output_html += ''; + output_html += '
    '; + } + } output_html += '
    '; output_html += '