diff --git a/CHANGELOG.md b/CHANGELOG.md index f93af2e1..49a4e2ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,10 +7,23 @@ 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. -## Since Last Release +## [v1.3.20-alpha](https://github.com/Lexpedite/blawx/releases/tag/v1.3.20-alpha) 2022-07-11 + +This release adds user registration, restricts access to projects that the user created, +and allows the user to create new projects from templates and tutorials. + +These features make it possible for Blawx to be used in a multi-user environment. ### Added -* User registration +* User registration - non-admin users can create user accounts for themselves. +* Users can now only see and interact with projects they created. + +### Changed +* Tutorials and Examples are now available from the New Project button. +* Updates to Beginner's Guide and Examples documentation. + +### Fixed +* A bug in the project import method has been fixed. ## [v1.3.19-alpha](https://github.com/Lexpedite/blawx/releases/tag/v1.3.19-alpha) 2022-07-07 diff --git a/blawx/admin.py b/blawx/admin.py index abfbaba3..5acff8d0 100644 --- a/blawx/admin.py +++ b/blawx/admin.py @@ -7,11 +7,15 @@ class WorkspaceAdmin(admin.ModelAdmin): fields = ['ruledoc','workspace_name','xml_content','scasp_encoding'] class RuleDocAdmin(admin.ModelAdmin): - fields = ['ruledoc_name','scasp_encoding','tutorial'] + fields = ['ruledoc_name','scasp_encoding','tutorial','owner'] class BlawxTestAdmin(admin.ModelAdmin): fields = ['ruledoc','test_name','xml_content','scasp_encoding', 'tutorial'] +# class RuleDocTemplateAdmin(admin.ModelAdmin): +# fields = ['template_name','yaml_content'] + admin.site.register(Workspace,WorkspaceAdmin) admin.site.register(RuleDoc,RuleDocAdmin) admin.site.register(BlawxTest,BlawxTestAdmin) +# admin.site.register(RuleDocTemplate,RuleDocTemplateAdmin) diff --git a/blawx/fixtures/accounts/demo.yaml b/blawx/fixtures/accounts/demo.yaml deleted file mode 100644 index 46dea5f8..00000000 --- a/blawx/fixtures/accounts/demo.yaml +++ /dev/null @@ -1,15 +0,0 @@ -- model: auth.user - pk: 3 - fields: - password: pbkdf2_sha256$320000$EYa6tD6PQmBXYtwTRPC0ea$S1xpa2WqgmNAPbHgaGKTy+6MC0zHPZT0Au0bJPx39tg= - last_login: null - is_superuser: false - username: demo - first_name: '' - last_name: '' - email: '' - is_staff: false - is_active: true - date_joined: 2022-06-27 20:30:41.275005+00:00 - groups: [] - user_permissions: [] \ No newline at end of file diff --git a/blawx/fixtures/docs/components/admin.yaml b/blawx/fixtures/docs/components/admin.yaml index b8b30bae..59bba0cd 100644 --- a/blawx/fixtures/docs/components/admin.yaml +++ b/blawx/fixtures/docs/components/admin.yaml @@ -8,27 +8,9 @@ The Blawx Administration Interface is available by navigating to `/admin` on your Blawx Server. - ## User Accounts - - The primary purpose of accessing the admin interface is currently to be able to create - user accounts. This can be done by logging into the admin interface using an - admin username and password, click on users on the left side of the screen, and clicking - "add user" on the top right of the users screen. - - Once you have created an account here, it will be possible for users to log in using that - account in the main Blawx Interface. - - Note that Blawx' user permissions currently require that the user be logged in to be able - to access anything other than the main page, the login screen, or the documentation. However, - all users have access to all functions of the server. - - More fine-grained user control will be implemented in future versions. + The admin interface can be used to view and make changes to the projects owned by anyone on the server, + and to add, change, and delete user accounts. By default, on a new installation of Blawx, there is an admin account created with the user name `admin` and the password `blawx2022`. When installing a server to which you want to - restrict access, make sure to change the admin password immediately. - - Servers will also be created with a demo account with the username `demo` and the password - `blawx2022`. This user account should be deleted in the admin interface if you are trying - to restrict access to your server. The demo account is capable of doing anything inside - the system except add and remove users and access the admin interface. \ No newline at end of file + restrict access, make sure to change the admin password immediately. \ No newline at end of file diff --git a/blawx/fixtures/docs/examples/beards.yaml b/blawx/fixtures/docs/examples/beards.yaml index 02763517..678968c3 100644 --- a/blawx/fixtures/docs/examples/beards.yaml +++ b/blawx/fixtures/docs/examples/beards.yaml @@ -5,11 +5,10 @@ content: | # Beard Tax Act - The Beard Tax Act example included with Blawx is [available here](/12/) (assuming it hasn't been - deleted from your system). + All the example projects are available under the New Project button. - It is an implemention inside Blawx of the Beard Tax Act rules as code demonstration task + This example is an implementation inside Blawx of the Beard Tax Act rules as code demonstration task described at [the Better Rules github page](https://github.com/BetterRules/example-rules-as-code). It includes a single test designed to be run inside BlawxBot. Open the project, click on the name - of the test, and click Bot to run the demo. \ No newline at end of file + of the test, and click "Bot" to run the demo. \ No newline at end of file diff --git a/blawx/fixtures/docs/examples/bird.yaml b/blawx/fixtures/docs/examples/bird.yaml index 3620a4d0..0bb9b124 100644 --- a/blawx/fixtures/docs/examples/bird.yaml +++ b/blawx/fixtures/docs/examples/bird.yaml @@ -5,8 +5,7 @@ content: | # Bird Act - The Bird Act example included with Blawx is [available here](/6/) (assuming it hasn't been - deleted from your system). + All the example projects are available under the New Project button. - It is used to demonstrate the use of defaults and exceptions, and references to source + The Bird Act example is used to demonstrate the use of defaults and exceptions, and references to source legislation in explanations. \ No newline at end of file diff --git a/blawx/fixtures/docs/examples/mortality.yaml b/blawx/fixtures/docs/examples/mortality.yaml index 701b0f5d..0f86ff69 100644 --- a/blawx/fixtures/docs/examples/mortality.yaml +++ b/blawx/fixtures/docs/examples/mortality.yaml @@ -5,7 +5,6 @@ content: | # Mortality Act - The Mortality Act example included with Blawx is [available here](/5/) (assuming it hasn't been - deleted from your system). + All the example projects are available under the New Project button. - It is used as a minimal example of a Blawx project. \ No newline at end of file + The Mortality Act example is used as a minimal example of a Blawx project. \ No newline at end of file diff --git a/blawx/fixtures/docs/examples/net30.yaml b/blawx/fixtures/docs/examples/net30.yaml index 0225f094..8a8f7512 100644 --- a/blawx/fixtures/docs/examples/net30.yaml +++ b/blawx/fixtures/docs/examples/net30.yaml @@ -5,7 +5,6 @@ content: | # Net 30 - The Net 30 example included with Blawx is [available here](/8/) (assuming it hasn't been - deleted from your system). + All the example projects are available under the New Project button. - It is used to demonstrate the use of dates and durations in Blawx. \ No newline at end of file + The Net 30 example is used to demonstrate the use of dates and durations in Blawx. \ No newline at end of file diff --git a/blawx/fixtures/docs/examples/r34.yaml b/blawx/fixtures/docs/examples/r34.yaml index 71cf4aa1..30701343 100644 --- a/blawx/fixtures/docs/examples/r34.yaml +++ b/blawx/fixtures/docs/examples/r34.yaml @@ -5,7 +5,6 @@ content: | # Rule 34 - The Rule 34 example included with Blawx is [available here](/4/) (assuming it hasn't been - deleted from your system). + All the example projects are available under the New Project button. - It is used to demonstrate the use of Blawx to detect drafting flaws in legislative texts. \ No newline at end of file + The Rule 34 example is used to demonstrate the use of Blawx to detect drafting flaws in legislative texts. \ No newline at end of file diff --git a/blawx/fixtures/docs/examples/rps.yaml b/blawx/fixtures/docs/examples/rps.yaml index 423ffada..7128a60f 100644 --- a/blawx/fixtures/docs/examples/rps.yaml +++ b/blawx/fixtures/docs/examples/rps.yaml @@ -5,10 +5,9 @@ content: | # Rock Paper Scissors Act - The Rock Paper Scissors Act example included with Blawx is [available here](/2/) (assuming it hasn't been - deleted from your system). + All the example projects are available under the New Project button. - It is used to demonstrate many different features of Blawx. + The Rock Paper Scissors Act example is used to demonstrate many different features of Blawx. A complete run-through of how to generate the Rule Paper Scissors example from scratch is available as [a tutorial in the Beginner's Guide](/docs/guide/rps). \ No newline at end of file diff --git a/blawx/fixtures/docs/examples/wills.yaml b/blawx/fixtures/docs/examples/wills.yaml index 03f48dc0..4e74254c 100644 --- a/blawx/fixtures/docs/examples/wills.yaml +++ b/blawx/fixtures/docs/examples/wills.yaml @@ -5,10 +5,9 @@ content: | # Wills Act - The Wills Act example included with Blawx is [available here](/9/) (assuming it hasn't been - deleted from your system). + All the example projects are available under the New Project button. - It is used to demonstrate the relevance reasoning features of the interview endpoint + The Wills Act example is used to demonstrate the relevance reasoning features of the interview endpoint for Blawx tests, as seen in BlawxBot. The rules set out that a person is entitled to make a will if they are over the age of 18, diff --git a/blawx/fixtures/docs/examples/wills_tutorial.yaml b/blawx/fixtures/docs/examples/wills_tutorial.yaml index 0b541a0e..39dfc2f5 100644 --- a/blawx/fixtures/docs/examples/wills_tutorial.yaml +++ b/blawx/fixtures/docs/examples/wills_tutorial.yaml @@ -5,10 +5,9 @@ content: | # Wills Act Tutorial - The Wills Act Tutorial included with Blawx is [available here](/14/) (assuming it hasn't been - deleted from your system). + All the tutorial projects are available under the New Project button. - It contains a single-section rule, a single test, and no code. Instead, if you click the "Tutorial" + The Wills Act Tutorial contains a single-section rule, a single test, and no code. Instead, if you click the "Tutorial" button in the button bar, it will take you through a short tutorial of how to encode your rule, test it, and deploy it using BlawxBot. diff --git a/blawx/fixtures/docs/guide/legal_text.yaml b/blawx/fixtures/docs/guide/legal_text.yaml index 70378529..93340e8a 100644 --- a/blawx/fixtures/docs/guide/legal_text.yaml +++ b/blawx/fixtures/docs/guide/legal_text.yaml @@ -48,11 +48,13 @@ ## Creating a New Project - To begin, go to [the root of your Blawx server](/), which will look something like this: + To begin, go to [the root of your Blawx server](/). You may need to create a user account if + you have not done so already. When you are logged in, the root of the server will look something like this: ![Blawx Root Screen](/static/blawx/docs/images/blawx_root_screen.png) - Once there, click "Create Rule". This will open the Project Editor screen, which will + Once there, click "New Project", and in the resulting drop-down choose "New Blank Project". + This will open the Project Editor screen, which will look like this: ![Project Editor Screen](/static/blawx/docs/images/project_editor_screen.png) diff --git a/blawx/migrations/0020_ruledoc_owner.py b/blawx/migrations/0020_ruledoc_owner.py new file mode 100644 index 00000000..372f6615 --- /dev/null +++ b/blawx/migrations/0020_ruledoc_owner.py @@ -0,0 +1,22 @@ +# Generated by Django 4.0.1 on 2022-07-08 18:25 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('blawx', '0019_blawxtest_tutorial'), + ] + + operations = [ + migrations.AddField( + model_name='ruledoc', + name='owner', + field=models.ForeignKey(default=3, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + preserve_default=False, + ), + ] diff --git a/blawx/migrations/0021_rename_xml_content_workspacetemplate_yaml_content.py b/blawx/migrations/0021_rename_xml_content_workspacetemplate_yaml_content.py new file mode 100644 index 00000000..c37d6148 --- /dev/null +++ b/blawx/migrations/0021_rename_xml_content_workspacetemplate_yaml_content.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0.1 on 2022-07-08 23:00 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('blawx', '0020_ruledoc_owner'), + ] + + operations = [ + migrations.RenameField( + model_name='workspacetemplate', + old_name='xml_content', + new_name='yaml_content', + ), + ] diff --git a/blawx/migrations/0022_rename_workspacetemplate_ruledoctemplate.py b/blawx/migrations/0022_rename_workspacetemplate_ruledoctemplate.py new file mode 100644 index 00000000..08608715 --- /dev/null +++ b/blawx/migrations/0022_rename_workspacetemplate_ruledoctemplate.py @@ -0,0 +1,17 @@ +# Generated by Django 4.0.1 on 2022-07-08 23:05 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('blawx', '0021_rename_xml_content_workspacetemplate_yaml_content'), + ] + + operations = [ + migrations.RenameModel( + old_name='WorkspaceTemplate', + new_name='RuleDocTemplate', + ), + ] diff --git a/blawx/migrations/0023_delete_ruledoctemplate.py b/blawx/migrations/0023_delete_ruledoctemplate.py new file mode 100644 index 00000000..c8f8215c --- /dev/null +++ b/blawx/migrations/0023_delete_ruledoctemplate.py @@ -0,0 +1,16 @@ +# Generated by Django 4.0.1 on 2022-07-11 18:40 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('blawx', '0022_rename_workspacetemplate_ruledoctemplate'), + ] + + operations = [ + migrations.DeleteModel( + name='RuleDocTemplate', + ), + ] diff --git a/blawx/models.py b/blawx/models.py index a7de3100..ce513104 100644 --- a/blawx/models.py +++ b/blawx/models.py @@ -1,4 +1,5 @@ from django.db import models +from django.contrib.auth.models import User from .parse_an import generate_tree from cobalt.hierarchical import Act from clean.clean import generate_akn @@ -10,6 +11,7 @@ class RuleDoc(models.Model): # akoma_ntoso = models.TextField(default="",blank=True) scasp_encoding = models.TextField(default="",blank=True) tutorial = models.TextField(default="",blank=True) + owner = models.ForeignKey(User,on_delete=models.CASCADE,) def __str__(self): return self.ruledoc_name @@ -52,12 +54,12 @@ class Meta: models.UniqueConstraint(fields=['ruledoc','test_name'],name='unique_test_and_ruledoc') ] -class WorkspaceTemplate(models.Model): - template_name = models.CharField(max_length=200) - xml_content = models.TextField(default="") +# class RuleDocTemplate(models.Model): +# template_name = models.CharField(max_length=200) +# yaml_content = models.TextField(default="") - def __str__(self): - return self.template_name +# def __str__(self): +# return self.template_name class Query(models.Model): ruledoc = models.ForeignKey(Workspace, on_delete=models.CASCADE) diff --git a/blawx/reasoner.py b/blawx/reasoner.py index 99b5e6f2..ce105477 100644 --- a/blawx/reasoner.py +++ b/blawx/reasoner.py @@ -1,4 +1,4 @@ -from django.http import Http404 +from django.http import Http404, HttpResponseNotFound from rest_framework.decorators import api_view, permission_classes, authentication_classes from rest_framework.response import Response @@ -125,274 +125,277 @@ def json_2_scasp(element,higher_order=False): else: return str(element) -@api_view(['GET', 'POST']) -@authentication_classes([SessionAuthentication]) -@permission_classes([IsAuthenticated]) -def run_query(request,workspace,query): +# @api_view(['GET', 'POST']) +# @authentication_classes([SessionAuthentication]) +# @permission_classes([IsAuthenticated]) +# def run_query(request,workspace,query): - # Collect the rules based on the ruleset specified - if workspace == "rps": - scasp_ruleset = """ -:- use_module(library(scasp)). - -#pred player(X) :: '@(X) is a player'. -#pred participate_in(Game,Player) :: '@(Player) participated in @(Game)'. -#pred winner(Game,Player) :: '@(Player) is the winner of @(Game)'. -#pred throw(Player,Sign) :: '@(Player) threw @(Sign)'. -#pred beat(Sign,OtherSign) :: '@(Sign) beats @(OtherSign)'. -#pred game(G) :: '@(G) is a game of rock-paper-scissors'. -#pred not_same_player(X,Y) :: '@(X) and @(Y) are not the same player'. - -beat(rock,scissors). -beat(scissors,paper). -beat(paper,rock). - -not_same_player(X,Y) :- - X \= Y. - -game_has_two_different_players(Game,Player,OtherPlayer) :- - game(Game), - player(Player), - not_same_player(Player,OtherPlayer), - player(OtherPlayer), - participate_in(Game,Player), - participate_in(Game,OtherPlayer). - -winner(Game,Player) :- - game_has_two_different_players(Game,Player,OtherPlayer), - throw(Player,Sign), - throw(OtherPlayer,OtherSign), - beat(Sign,OtherSign). -""" - rulefile = tempfile.NamedTemporaryFile('w',delete=False) - rulefile.write(scasp_ruleset) - rulefile.close() - rulefilename = rulefile.name - else: - return Http404("Workspace not found") - - # Collect the query based on the query specified in the URL - if query == "winner": - scasp_query = "winner(G,P)" - else: - return Http404("Query not found") +# # Collect the rules based on the ruleset specified +# if workspace == "rps": +# scasp_ruleset = """ +# :- use_module(library(scasp)). + +# #pred player(X) :: '@(X) is a player'. +# #pred participate_in(Game,Player) :: '@(Player) participated in @(Game)'. +# #pred winner(Game,Player) :: '@(Player) is the winner of @(Game)'. +# #pred throw(Player,Sign) :: '@(Player) threw @(Sign)'. +# #pred beat(Sign,OtherSign) :: '@(Sign) beats @(OtherSign)'. +# #pred game(G) :: '@(G) is a game of rock-paper-scissors'. +# #pred not_same_player(X,Y) :: '@(X) and @(Y) are not the same player'. + +# beat(rock,scissors). +# beat(scissors,paper). +# beat(paper,rock). + +# not_same_player(X,Y) :- +# X \= Y. + +# game_has_two_different_players(Game,Player,OtherPlayer) :- +# game(Game), +# player(Player), +# not_same_player(Player,OtherPlayer), +# player(OtherPlayer), +# participate_in(Game,Player), +# participate_in(Game,OtherPlayer). + +# winner(Game,Player) :- +# game_has_two_different_players(Game,Player,OtherPlayer), +# throw(Player,Sign), +# throw(OtherPlayer,OtherSign), +# beat(Sign,OtherSign). +# """ +# rulefile = tempfile.NamedTemporaryFile('w',delete=False) +# rulefile.write(scasp_ruleset) +# rulefile.close() +# rulefilename = rulefile.name +# else: +# return Http404("Workspace not found") + +# # Collect the query based on the query specified in the URL +# if query == "winner": +# scasp_query = "winner(G,P)" +# else: +# return Http404("Query not found") - # Collect the data provided, and convert it into s(CASP) statements. - if request.method == "GET": - translated_facts = """ -game(testgame). -player(bob). -player(jane). -participate_in(testgame,bob). -participate_in(testgame,jane). -throw(bob,rock). -throw(jane,scissors).""" - - elif request.method == "POST": - translated_facts = json_2_scasp(request.get_json()) +# # Collect the data provided, and convert it into s(CASP) statements. +# if request.method == "GET": +# translated_facts = """ +# game(testgame). +# player(bob). +# player(jane). +# participate_in(testgame,bob). +# participate_in(testgame,jane). +# throw(bob,rock). +# throw(jane,scissors).""" + +# elif request.method == "POST": +# translated_facts = json_2_scasp(request.get_json()) - # Start the Prolog "thread" - with PrologMQI() as swipl: - with swipl.create_thread() as swipl_thread: +# # Start the Prolog "thread" +# with PrologMQI() as swipl: +# with swipl.create_thread() as swipl_thread: - file = open(rulefilename,'a') +# file = open(rulefilename,'a') - file.write(translated_facts) +# file.write(translated_facts) - file.close() - file = open(rulefilename,'r') - transcript = open("transcript","w") - transcript.write("Loading " + rulefilename + ", the contents of which are:\n") - transcript.write(file.read() + '\n') - # print(file.read()) - file.close() +# file.close() +# file = open(rulefilename,'r') +# transcript = open("transcript","w") +# transcript.write("Loading " + rulefilename + ", the contents of which are:\n") +# transcript.write(file.read() + '\n') +# # print(file.read()) +# file.close() - with redirect_stderr(transcript): - load_file_answer = swipl_thread.query("['" + rulefilename + "'].") - transcript.write(str(load_file_answer) + '\n') - if os.path.exists(rulefilename): - os.remove(rulefilename) - - # Execute the requested query. - transcript.write("scasp(" + scasp_query + "),scasp_embed:scasp_justification(J,[]),with_output_to(string(JOut), scasp_just_human:human_justification_tree(J,[])).\n") - with redirect_stderr(transcript): - query_answer = swipl_thread.query("scasp(" + scasp_query + "),scasp_embed:scasp_justification(J,[]),with_output_to(string(JOut), scasp_just_human:human_justification_tree(J,[])).") - transcript.write(str(query_answer) + '\n') +# with redirect_stderr(transcript): +# load_file_answer = swipl_thread.query("['" + rulefilename + "'].") +# transcript.write(str(load_file_answer) + '\n') +# if os.path.exists(rulefilename): +# os.remove(rulefilename) + +# # Execute the requested query. +# transcript.write("scasp(" + scasp_query + "),scasp_embed:scasp_justification(J,[]),with_output_to(string(JOut), scasp_just_human:human_justification_tree(J,[])).\n") +# with redirect_stderr(transcript): +# query_answer = swipl_thread.query("scasp(" + scasp_query + "),scasp_embed:scasp_justification(J,[]),with_output_to(string(JOut), scasp_just_human:human_justification_tree(J,[])).") +# transcript.write(str(query_answer) + '\n') - transcript.close() - transcript = open("transcript",'r') - transcript_output = transcript.read() - transcript.close() - os.remove('transcript') +# transcript.close() +# transcript = open("transcript",'r') +# transcript_output = transcript.read() +# transcript.close() +# os.remove('transcript') - if type(query_answer) is not list: - query_output = query_answer - else: - query_output = query_answer[0] - - # Return the results as JSON - return Response({ "answer": query_output, "transcript": transcript_output }) - -@api_view(['POST']) -@authentication_classes([SessionAuthentication]) -@permission_classes([IsAuthenticated]) -def run_ruledoc(request,pk): - translated_facts = "" - if request.data: - translated_facts = json_2_scasp(request.data) - wss = Workspace.objects.filter(ruledoc=RuleDoc.objects.get(pk=pk)) - ruleset = "" - for ws in wss: - ruleset += ws.scasp_encoding - query = "No Query Specified" - for line in ruleset.splitlines(): - if line.startswith("?- "): - query = line[3:-1] # remove query prompt and period. - full_query = "scasp(" + query + ",[tree(Tree)]),with_output_to(string(Human), human_justification_tree(Tree,[]))." - rulefile = tempfile.NamedTemporaryFile('w',delete=False) - rulefile.write(":- use_module(library(scasp)).\n") - rulefile.write(":- use_module(library(scasp/human)).\n") - rulefile.write(translated_facts) - rulefile.write(ruleset) - rulefile.close() - rulefilename = rulefile.name - - # Start the Prolog "thread" - try: - with PrologMQI() as swipl: - with swipl.create_thread() as swipl_thread: - - transcript = tempfile.NamedTemporaryFile('w',delete=False,prefix="transcript_") - transcript_name = transcript.name - - with redirect_stderr(transcript): - load_file_answer = swipl_thread.query("['" + rulefilename + "'].") - transcript.write(str(load_file_answer) + '\n') - if os.path.exists(rulefilename): - os.remove(rulefilename) +# if type(query_answer) is not list: +# query_output = query_answer +# else: +# query_output = query_answer[0] + +# # Return the results as JSON +# return Response({ "answer": query_output, "transcript": transcript_output }) + +# @api_view(['POST']) +# @authentication_classes([SessionAuthentication]) +# @permission_classes([IsAuthenticated]) +# def run_ruledoc(request,pk): +# translated_facts = "" +# if request.data: +# translated_facts = json_2_scasp(request.data) +# wss = Workspace.objects.filter(ruledoc=RuleDoc.objects.get(pk=pk)) +# ruleset = "" +# for ws in wss: +# ruleset += ws.scasp_encoding +# query = "No Query Specified" +# for line in ruleset.splitlines(): +# if line.startswith("?- "): +# query = line[3:-1] # remove query prompt and period. +# full_query = "scasp(" + query + ",[tree(Tree)]),with_output_to(string(Human), human_justification_tree(Tree,[]))." +# rulefile = tempfile.NamedTemporaryFile('w',delete=False) +# rulefile.write(":- use_module(library(scasp)).\n") +# rulefile.write(":- use_module(library(scasp/human)).\n") +# rulefile.write(translated_facts) +# rulefile.write(ruleset) +# rulefile.close() +# rulefilename = rulefile.name + +# # Start the Prolog "thread" +# try: +# with PrologMQI() as swipl: +# with swipl.create_thread() as swipl_thread: + +# transcript = tempfile.NamedTemporaryFile('w',delete=False,prefix="transcript_") +# transcript_name = transcript.name + +# with redirect_stderr(transcript): +# load_file_answer = swipl_thread.query("['" + rulefilename + "'].") +# transcript.write(str(load_file_answer) + '\n') +# if os.path.exists(rulefilename): +# os.remove(rulefilename) + +# transcript.write(full_query) +# with redirect_stderr(transcript): +# query_answer = swipl_thread.query(full_query) +# transcript.write(str(query_answer) + '\n') + +# transcript.close() +# transcript = open(transcript_name,'r') +# # transcript = open("transcript",'r') +# transcript_output = transcript.read() +# transcript.close() +# os.remove(transcript_name) +# except PrologError as err: +# return Response({ "error": "There was an error while running the code.", "transcript": err.prolog() }) +# except PrologLaunchError as err: +# query_answer = "Blawx could not load the reasoner." +# return Response({ "error": "Blawx could not load the reasoner." }) +# # Return the results as JSON +# return Response({ "answer": json.dumps(query_answer), "transcript": transcript_output }) - transcript.write(full_query) - with redirect_stderr(transcript): - query_answer = swipl_thread.query(full_query) - transcript.write(str(query_answer) + '\n') - - transcript.close() - transcript = open(transcript_name,'r') - # transcript = open("transcript",'r') - transcript_output = transcript.read() - transcript.close() - os.remove(transcript_name) - except PrologError as err: - return Response({ "error": "There was an error while running the code.", "transcript": err.prolog() }) - except PrologLaunchError as err: - query_answer = "Blawx could not load the reasoner." - return Response({ "error": "Blawx could not load the reasoner." }) - # Return the results as JSON - return Response({ "answer": json.dumps(query_answer), "transcript": transcript_output }) - - @api_view(['POST']) @authentication_classes([SessionAuthentication]) @permission_classes([IsAuthenticated]) def run_test(request,ruledoc,test_name): - translated_facts = "" - if request.data: - translated_facts = new_json_2_scasp(request.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) - ruleset = "" - for ws in wss: - ruleset += "\n\n" + ws.scasp_encoding - ruleset += "\n\n" + test.scasp_encoding - # print(ruleset) - - rulefile = tempfile.NamedTemporaryFile('w',delete=False) - rulefile.write(""" -:- use_module(library(scasp)). -:- use_module(library(scasp/human)). -:- use_module(library(scasp/output)). - -:- meta_predicate - blawxrun2(0,-). -""") - - query = "No Query Specified" - for line in test.scasp_encoding.splitlines(): - if line.startswith("?- "): - query = line[3:-1] # remove query prompt and period. - - rulefile.write(""" -blawxrun(Query, Human) :- - scasp(Query,[tree(Tree)]), - ovar_analyze_term(t(Query, Tree),[name_constraints(true)]), - with_output_to(string(Human), - human_justification_tree(Tree,[])). - term_attvars(Query, AttVars), - maplist(del_attrs, AttVars). -""") - # For Each Variable in the query -# for v in get_variables(query): -# rulefile.write("ovar_analyze_term(t(" + v + ", Tree),[name_constraints(true)]),") -# rulefile.write(""" -# with_output_to(string(Human), -# human_justification_tree(Tree,[])). -# """) - - rulefile.write(ldap_code + '\n\n') - rulefile.write(scasp_dates + '\n\n') - - - rulefile.write(translated_facts) - rulefile.write(ruleset) - rulefile.close() - rulefilename = rulefile.name - temprulefile = open(rulefilename,'r') - print(temprulefile.read()) - temprulefile.close() - - # Start the Prolog "thread" - try: - with PrologMQI() as swipl: - with swipl.create_thread() as swipl_thread: - - transcript = tempfile.NamedTemporaryFile('w',delete=False,prefix="transcript_") - transcript_name = transcript.name - - with redirect_stderr(transcript): - load_file_answer = swipl_thread.query("['" + rulefilename + "'].") - transcript.write(str(load_file_answer) + '\n') - if os.path.exists(rulefilename): - rules = open(rulefilename) - rulestext = rules.read() - transcript.write(rulestext + '\n') - rules.close() - os.remove(rulefilename) - - #transcript.write(full_query) - with redirect_stderr(transcript): - print("blawxrun(" + query + ",Human).") - query_answer = swipl_thread.query("blawxrun(" + query + ",Human).") - - transcript.write(str(query_answer) + '\n') - - transcript.close() - transcript = open(transcript_name,'r') - # transcript = open("transcript",'r') - transcript_output = transcript.read() - transcript.close() - os.remove(transcript_name) - except PrologError as err: - return Response({ "error": "There was an error while running the code.", "transcript": err.prolog() }) - except PrologLaunchError as err: - query_answer = "Blawx could not load the reasoner." - return Response({ "error": "Blawx could not load the reasoner." }) - # Return the results as JSON - if query_answer == False: - return Response({ "Answers": [], "Transcript": transcript_output }) + ruledoctest = RuleDoc.objects.filter(pk=ruledoc,owner=request.user) + if ruledoctest.exists(): + translated_facts = "" + if request.data: + translated_facts = new_json_2_scasp(request.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) + ruleset = "" + for ws in wss: + ruleset += "\n\n" + ws.scasp_encoding + ruleset += "\n\n" + test.scasp_encoding + # print(ruleset) + + rulefile = tempfile.NamedTemporaryFile('w',delete=False) + rulefile.write(""" + :- use_module(library(scasp)). + :- use_module(library(scasp/human)). + :- use_module(library(scasp/output)). + + :- meta_predicate + blawxrun2(0,-). + """) + + query = "No Query Specified" + for line in test.scasp_encoding.splitlines(): + if line.startswith("?- "): + query = line[3:-1] # remove query prompt and period. + + rulefile.write(""" + blawxrun(Query, Human) :- + scasp(Query,[tree(Tree)]), + ovar_analyze_term(t(Query, Tree),[name_constraints(true)]), + with_output_to(string(Human), + human_justification_tree(Tree,[])). + term_attvars(Query, AttVars), + maplist(del_attrs, AttVars). + """) + # For Each Variable in the query + # for v in get_variables(query): + # rulefile.write("ovar_analyze_term(t(" + v + ", Tree),[name_constraints(true)]),") + # rulefile.write(""" + # with_output_to(string(Human), + # human_justification_tree(Tree,[])). + # """) + + rulefile.write(ldap_code + '\n\n') + rulefile.write(scasp_dates + '\n\n') + + + rulefile.write(translated_facts) + rulefile.write(ruleset) + rulefile.close() + rulefilename = rulefile.name + temprulefile = open(rulefilename,'r') + print(temprulefile.read()) + temprulefile.close() + + # Start the Prolog "thread" + try: + with PrologMQI() as swipl: + with swipl.create_thread() as swipl_thread: + + transcript = tempfile.NamedTemporaryFile('w',delete=False,prefix="transcript_") + transcript_name = transcript.name + + with redirect_stderr(transcript): + load_file_answer = swipl_thread.query("['" + rulefilename + "'].") + transcript.write(str(load_file_answer) + '\n') + if os.path.exists(rulefilename): + rules = open(rulefilename) + rulestext = rules.read() + transcript.write(rulestext + '\n') + rules.close() + os.remove(rulefilename) + + #transcript.write(full_query) + with redirect_stderr(transcript): + print("blawxrun(" + query + ",Human).") + query_answer = swipl_thread.query("blawxrun(" + query + ",Human).") + + transcript.write(str(query_answer) + '\n') + + transcript.close() + transcript = open(transcript_name,'r') + # transcript = open("transcript",'r') + transcript_output = transcript.read() + transcript.close() + os.remove(transcript_name) + except PrologError as err: + return Response({ "error": "There was an error while running the code.", "transcript": err.prolog() }) + except PrologLaunchError as err: + query_answer = "Blawx could not load the reasoner." + return Response({ "error": "Blawx could not load the reasoner." }) + # Return the results as JSON + if query_answer == False: + return Response({ "Answers": [], "Transcript": transcript_output }) + else: + return Response({ "Answers": generate_answers(query_answer), "Transcript": transcript_output }) else: - return Response({ "Answers": generate_answers(query_answer), "Transcript": transcript_output }) + return HttpResponseNotFound() def get_ontology_internal(ruledoc,test_name): wss = Workspace.objects.filter(ruledoc=RuleDoc.objects.get(pk=ruledoc)) @@ -540,235 +543,243 @@ def get_ontology_internal(ruledoc,test_name): @authentication_classes([SessionAuthentication]) @permission_classes([IsAuthenticated]) def get_ontology(request,ruledoc,test_name): - result = get_ontology_internal(ruledoc,test_name) - return Response(result) + ruledoctest = RuleDoc.objects.filter(owner=request.user,pk=ruledoc) + if ruledoctest.exists(): + result = get_ontology_internal(ruledoc,test_name) + return Response(result) + else: + return HttpResponseNotFound() @api_view(['POST']) @authentication_classes([SessionAuthentication]) @permission_classes([IsAuthenticated]) def interview(request,ruledoc,test_name): - translated_facts = "" - if request.data: - translated_facts = new_json_2_scasp(request.data, True) #Generate answers ignoring 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) - ruleset = "" - for ws in wss: - ruleset += "\n\n" + ws.scasp_encoding - ruleset += "\n\n" + test.scasp_encoding - # print(ruleset) - - rulefile = tempfile.NamedTemporaryFile('w',delete=False) - rulefile.write(""" -:- use_module(library(scasp)). -:- use_module(library(scasp/human)). -:- use_module(library(scasp/output)). - -:- meta_predicate - blawxrun2(0,-). -""") - - query = "No Query Specified" - for line in test.scasp_encoding.splitlines(): - if line.startswith("?- "): - query = line[3:-1] # remove query prompt and period. - - rulefile.write(""" -blawxrun(Query, Human) :- - scasp(Query,[tree(Tree)]), - ovar_analyze_term(t(Query, Tree),[name_constraints(true)]), - with_output_to(string(Human), - human_justification_tree(Tree,[])). - term_attvars(Query, AttVars), - maplist(del_attrs, AttVars). -""") - # For Each Variable in the query -# for v in get_variables(query): -# rulefile.write("ovar_analyze_term(t(" + v + ", Tree),[name_constraints(true)]),") -# rulefile.write(""" -# with_output_to(string(Human), -# human_justification_tree(Tree,[])). -# """) - - rulefile.write(ldap_code + '\n\n') - rulefile.write(scasp_dates + '\n\n') - - - rulefile.write(translated_facts) - rulefile.write(ruleset) - rulefile.close() - rulefilename = rulefile.name - temprulefile = open(rulefilename,'r') - print(temprulefile.read()) - temprulefile.close() - - # Start the Prolog "thread" - try: - with PrologMQI() as swipl: - with swipl.create_thread() as swipl_thread: - - transcript = tempfile.NamedTemporaryFile('w',delete=False,prefix="transcript_") - transcript_name = transcript.name - - with redirect_stderr(transcript): - load_file_answer = swipl_thread.query("['" + rulefilename + "'].") - transcript.write(str(load_file_answer) + '\n') - if os.path.exists(rulefilename): - rules = open(rulefilename) - rulestext = rules.read() - transcript.write(rulestext + '\n') - rules.close() - os.remove(rulefilename) - - #transcript.write(full_query) - with redirect_stderr(transcript): - print("blawxrun(" + query + ",Human).") - query_answer = swipl_thread.query("blawxrun(" + query + ",Human).") - - transcript.write(str(query_answer) + '\n') - - transcript.close() - transcript = open(transcript_name,'r') - # transcript = open("transcript",'r') - transcript_output = transcript.read() - transcript.close() - os.remove(transcript_name) - except PrologError as err: - return Response({ "error": "There was an error while running the code.", "transcript": err.prolog() }) - except PrologLaunchError as err: - query_answer = "Blawx could not load the reasoner." - return Response({ "error": "Blawx could not load the reasoner." }) - - # Now get the ontology information to be able to generate the relevance data - # Later, we will need to run the query again with assumptions in order to determine relevance. - # For now, we are just filling the data structure with all the categories and attributes. - # - # Old Version: - # ontology = get_ontology_internal(ruledoc,test_name) - # relevant_categories = ontology['Categories'] - # relevant_attributes = [] - # for a in ontology['Attributes']: - # relevant_attributes.append({"Attribute": a['Attribute']}) - # Effectively, we're going to start over. - translated_facts = "" - if request.data: - translated_facts = new_json_2_scasp(request.data, False) #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) - ruleset = "" - for ws in wss: - ruleset += "\n\n" + ws.scasp_encoding - ruleset += "\n\n" + test.scasp_encoding - - rulefile = tempfile.NamedTemporaryFile('w',delete=False) - rulefile.write(""" -:- use_module(library(scasp)). -:- use_module(library(scasp/human)). -:- use_module(library(scasp/output)). - -:- meta_predicate - blawxrun2(0,-). -""") - - query = "No Query Specified" - for line in test.scasp_encoding.splitlines(): - if line.startswith("?- "): - query = line[3:-1] # remove query prompt and period. - - rulefile.write(""" -blawxrun(Query, Tree, Model) :- - scasp(Query,[tree(Tree),model(Model)]), - ovar_analyze_term(t(Query, Tree),[name_constraints(true)]). -""") - - rulefile.write(ldap_code + '\n\n') - rulefile.write(scasp_dates + '\n\n') - - - rulefile.write(translated_facts) - rulefile.write(ruleset) - rulefile.close() - rulefilename = rulefile.name - temprulefile = open(rulefilename,'r') - print(temprulefile.read()) - temprulefile.close() - - # Start the Prolog "thread" - try: - with PrologMQI() as swipl: - with swipl.create_thread() as swipl_thread: - - transcript = tempfile.NamedTemporaryFile('w',delete=False,prefix="transcript_") - transcript_name = transcript.name - - with redirect_stderr(transcript): - load_file_answer = swipl_thread.query("['" + rulefilename + "'].") - transcript.write(str(load_file_answer) + '\n') - if os.path.exists(rulefilename): - rules = open(rulefilename) - rulestext = rules.read() - transcript.write(rulestext + '\n') - rules.close() - os.remove(rulefilename) + ruledoctest = RuleDoc.objects.filter(owner=request.user,pk=ruledoc) + if ruledoctest.exists(): + translated_facts = "" + if request.data: + translated_facts = new_json_2_scasp(request.data, True) #Generate answers ignoring 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) + ruleset = "" + for ws in wss: + ruleset += "\n\n" + ws.scasp_encoding + ruleset += "\n\n" + test.scasp_encoding + # print(ruleset) + + rulefile = tempfile.NamedTemporaryFile('w',delete=False) + rulefile.write(""" + :- use_module(library(scasp)). + :- use_module(library(scasp/human)). + :- use_module(library(scasp/output)). + + :- meta_predicate + blawxrun2(0,-). + """) + + query = "No Query Specified" + for line in test.scasp_encoding.splitlines(): + if line.startswith("?- "): + query = line[3:-1] # remove query prompt and period. + + rulefile.write(""" + blawxrun(Query, Human) :- + scasp(Query,[tree(Tree)]), + ovar_analyze_term(t(Query, Tree),[name_constraints(true)]), + with_output_to(string(Human), + human_justification_tree(Tree,[])). + term_attvars(Query, AttVars), + maplist(del_attrs, AttVars). + """) + # For Each Variable in the query + # for v in get_variables(query): + # rulefile.write("ovar_analyze_term(t(" + v + ", Tree),[name_constraints(true)]),") + # rulefile.write(""" + # with_output_to(string(Human), + # human_justification_tree(Tree,[])). + # """) + + rulefile.write(ldap_code + '\n\n') + rulefile.write(scasp_dates + '\n\n') + + + rulefile.write(translated_facts) + rulefile.write(ruleset) + rulefile.close() + rulefilename = rulefile.name + temprulefile = open(rulefilename,'r') + print(temprulefile.read()) + temprulefile.close() + + # Start the Prolog "thread" + try: + with PrologMQI() as swipl: + with swipl.create_thread() as swipl_thread: + + transcript = tempfile.NamedTemporaryFile('w',delete=False,prefix="transcript_") + transcript_name = transcript.name + + with redirect_stderr(transcript): + load_file_answer = swipl_thread.query("['" + rulefilename + "'].") + transcript.write(str(load_file_answer) + '\n') + if os.path.exists(rulefilename): + rules = open(rulefilename) + rulestext = rules.read() + transcript.write(rulestext + '\n') + rules.close() + os.remove(rulefilename) + + #transcript.write(full_query) + with redirect_stderr(transcript): + print("blawxrun(" + query + ",Human).") + query_answer = swipl_thread.query("blawxrun(" + query + ",Human).") + + transcript.write(str(query_answer) + '\n') + + transcript.close() + transcript = open(transcript_name,'r') + # transcript = open("transcript",'r') + transcript_output = transcript.read() + transcript.close() + os.remove(transcript_name) + except PrologError as err: + return Response({ "error": "There was an error while running the code.", "transcript": err.prolog() }) + except PrologLaunchError as err: + query_answer = "Blawx could not load the reasoner." + return Response({ "error": "Blawx could not load the reasoner." }) + + # Now get the ontology information to be able to generate the relevance data + # Later, we will need to run the query again with assumptions in order to determine relevance. + # For now, we are just filling the data structure with all the categories and attributes. + # + # Old Version: + # ontology = get_ontology_internal(ruledoc,test_name) + # relevant_categories = ontology['Categories'] + # relevant_attributes = [] + # for a in ontology['Attributes']: + # relevant_attributes.append({"Attribute": a['Attribute']}) + # Effectively, we're going to start over. + translated_facts = "" + if request.data: + translated_facts = new_json_2_scasp(request.data, False) #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) + ruleset = "" + for ws in wss: + ruleset += "\n\n" + ws.scasp_encoding + ruleset += "\n\n" + test.scasp_encoding + + rulefile = tempfile.NamedTemporaryFile('w',delete=False) + rulefile.write(""" + :- use_module(library(scasp)). + :- use_module(library(scasp/human)). + :- use_module(library(scasp/output)). + + :- meta_predicate + blawxrun2(0,-). + """) + + query = "No Query Specified" + for line in test.scasp_encoding.splitlines(): + if line.startswith("?- "): + query = line[3:-1] # remove query prompt and period. + + rulefile.write(""" + blawxrun(Query, Tree, Model) :- + scasp(Query,[tree(Tree),model(Model)]), + ovar_analyze_term(t(Query, Tree),[name_constraints(true)]). + """) + + rulefile.write(ldap_code + '\n\n') + rulefile.write(scasp_dates + '\n\n') + + + rulefile.write(translated_facts) + rulefile.write(ruleset) + rulefile.close() + rulefilename = rulefile.name + temprulefile = open(rulefilename,'r') + print(temprulefile.read()) + temprulefile.close() + + # Start the Prolog "thread" + try: + with PrologMQI() as swipl: + with swipl.create_thread() as swipl_thread: + + transcript = tempfile.NamedTemporaryFile('w',delete=False,prefix="transcript_") + transcript_name = transcript.name + + with redirect_stderr(transcript): + load_file_answer = swipl_thread.query("['" + rulefilename + "'].") + transcript.write(str(load_file_answer) + '\n') + if os.path.exists(rulefilename): + rules = open(rulefilename) + rulestext = rules.read() + transcript.write(rulestext + '\n') + rules.close() + os.remove(rulefilename) + + #transcript.write(full_query) + with redirect_stderr(transcript): + print("blawxrun(" + query + ",Human,Model).") + relevance_query_answer = swipl_thread.query("blawxrun(" + query + ",Human, Model).") + + transcript.write(str(relevance_query_answer) + '\n') + + transcript.close() + transcript = open(transcript_name,'r') + # transcript = open("transcript",'r') + transcript_output += transcript.read() # Adding to the transcript instead of setting it. + transcript.close() + os.remove(transcript_name) + except PrologError as err: + return Response({ "error": "There was an error while running the code.", "transcript": err.prolog() }) + except PrologLaunchError as err: + query_answer = "Blawx could not load the reasoner." + return Response({ "error": "Blawx could not load the reasoner." }) + + # Okay, the relevance query is running properly, and including terms in the results. + # Now I need to generate relevant categories and relevant attributes from the contents. + # The way to do that is to go through the terms, find the ones that have been assumed. + + # The relevant categories are the categories for which there is an assumed member of a category in the results. + # It is assumed if it justified with a chs(category(term)) in the tree. The term can be a symbol or an atom. + # It makes a difference. If it is a variable, then the unground term is valid. If it is a symbol, the ground + # term is valid, but not necessarily the unground term, unless it is valid elsewhere. + # Similarly for attributes. if there exists chs(attribute(object,value)) in the tree, then it was assumed. + + # So we could start by just pulling out anything that appears inside chs, and then processing those. + assumptions = [] + useful_assumptions = [] + relevant_categories = [] + relevant_attributes= [] + relevance_answers_processed = generate_answers(relevance_query_answer, False) + for a in relevance_answers_processed: + for m in a['Models']: + assumptions.extend(find_assumptions(m['Tree'])) + # print("Found Assumptions:") + # pprint(assumptions) + for a in assumptions: + if a['functor'] == 'not' and a['args'][0]['functor'] == 'abducible$$': + pass + elif simplify_term(a) not in useful_assumptions: + useful_assumptions.append(simplify_term(a)) + for ua in useful_assumptions: + if len(ua['args']) == 1: + relevant_categories.append(ua['functor']) + else: + relevant_attributes.append({'Attribute': ua['functor'], 'Arguments': ua['args']}) - #transcript.write(full_query) - with redirect_stderr(transcript): - print("blawxrun(" + query + ",Human,Model).") - relevance_query_answer = swipl_thread.query("blawxrun(" + query + ",Human, Model).") - - transcript.write(str(relevance_query_answer) + '\n') - transcript.close() - transcript = open(transcript_name,'r') - # transcript = open("transcript",'r') - transcript_output += transcript.read() # Adding to the transcript instead of setting it. - transcript.close() - os.remove(transcript_name) - except PrologError as err: - return Response({ "error": "There was an error while running the code.", "transcript": err.prolog() }) - except PrologLaunchError as err: - query_answer = "Blawx could not load the reasoner." - return Response({ "error": "Blawx could not load the reasoner." }) - - # Okay, the relevance query is running properly, and including terms in the results. - # Now I need to generate relevant categories and relevant attributes from the contents. - # The way to do that is to go through the terms, find the ones that have been assumed. - - # The relevant categories are the categories for which there is an assumed member of a category in the results. - # It is assumed if it justified with a chs(category(term)) in the tree. The term can be a symbol or an atom. - # It makes a difference. If it is a variable, then the unground term is valid. If it is a symbol, the ground - # term is valid, but not necessarily the unground term, unless it is valid elsewhere. - # Similarly for attributes. if there exists chs(attribute(object,value)) in the tree, then it was assumed. - - # So we could start by just pulling out anything that appears inside chs, and then processing those. - assumptions = [] - useful_assumptions = [] - relevant_categories = [] - relevant_attributes= [] - relevance_answers_processed = generate_answers(relevance_query_answer, False) - for a in relevance_answers_processed: - for m in a['Models']: - assumptions.extend(find_assumptions(m['Tree'])) - # print("Found Assumptions:") - # pprint(assumptions) - for a in assumptions: - if a['functor'] == 'not' and a['args'][0]['functor'] == 'abducible$$': - pass - elif simplify_term(a) not in useful_assumptions: - useful_assumptions.append(simplify_term(a)) - for ua in useful_assumptions: - if len(ua['args']) == 1: - relevant_categories.append(ua['functor']) + + # Return the results as JSON + if query_answer == False: + return Response({ "Answers": [], "Relevant Categories": relevant_categories, "Relevant Attributes": relevant_attributes, "Transcript": transcript_output }) else: - relevant_attributes.append({'Attribute': ua['functor'], 'Arguments': ua['args']}) - - - - # Return the results as JSON - if query_answer == False: - return Response({ "Answers": [], "Relevant Categories": relevant_categories, "Relevant Attributes": relevant_attributes, "Transcript": transcript_output }) + return Response({ "Answers": generate_answers(query_answer), "Relevant Categories": relevant_categories, "Relevant Attributes": relevant_attributes, "Transcript": transcript_output }) else: - return Response({ "Answers": generate_answers(query_answer), "Relevant Categories": relevant_categories, "Relevant Attributes": relevant_attributes, "Transcript": transcript_output }) + return HttpResponseNotFound() diff --git a/blawx/static/blawx/docs/images/blawx_root_screen.png b/blawx/static/blawx/docs/images/blawx_root_screen.png index 4f70c82e..90c61747 100644 Binary files a/blawx/static/blawx/docs/images/blawx_root_screen.png and b/blawx/static/blawx/docs/images/blawx_root_screen.png differ diff --git a/blawx/static/blawx/docs/images/blawx_root_with_new_project.png b/blawx/static/blawx/docs/images/blawx_root_with_new_project.png index 1e4b66a3..8c1780c3 100644 Binary files a/blawx/static/blawx/docs/images/blawx_root_with_new_project.png and b/blawx/static/blawx/docs/images/blawx_root_with_new_project.png differ diff --git a/blawx/fixtures/workspace/beard_tax.yaml b/blawx/static/blawx/examples/beard_tax.yaml similarity index 99% rename from blawx/fixtures/workspace/beard_tax.yaml rename to blawx/static/blawx/examples/beard_tax.yaml index 85cf4ca5..2fdd9f7e 100644 --- a/blawx/fixtures/workspace/beard_tax.yaml +++ b/blawx/static/blawx/examples/beard_tax.yaml @@ -1,6 +1,7 @@ - model: blawx.ruledoc pk: 12 fields: + owner: 3 ruledoc_name: Beard Tax Act rule_text: "Beard Tax Act\r\n\r\n1. In this Act, beard means any facial hair no shorter than 5 millimetres in\r\nlength that:\r\n (a) occurs on or below the diff --git a/blawx/fixtures/workspace/bird.yaml b/blawx/static/blawx/examples/bird.yaml similarity index 99% rename from blawx/fixtures/workspace/bird.yaml rename to blawx/static/blawx/examples/bird.yaml index 8690773a..338e430d 100644 --- a/blawx/fixtures/workspace/bird.yaml +++ b/blawx/static/blawx/examples/bird.yaml @@ -1,6 +1,7 @@ - model: blawx.ruledoc pk: 6 fields: + owner: 3 ruledoc_name: Bird Act rule_text: "Bird Act\r\n\r\n1. A Penguin is a Bird.\r\n2. If a thing is a bird, it flies, [penguin]{unless it is a penguin}." diff --git a/blawx/fixtures/workspace/mbp.yaml b/blawx/static/blawx/examples/mbp.yaml similarity index 99% rename from blawx/fixtures/workspace/mbp.yaml rename to blawx/static/blawx/examples/mbp.yaml index 6bd26a84..2104dd95 100644 --- a/blawx/fixtures/workspace/mbp.yaml +++ b/blawx/static/blawx/examples/mbp.yaml @@ -1,6 +1,7 @@ - model: blawx.ruledoc pk: 13 fields: + owner: 3 ruledoc_name: Motor Breakdown Policy rule_text: "Motor Breakdown Policy\r\n\r\nMEANING OF WORDS \r\n1. Wherever the following words and phrases appear in bold in this document, they will always diff --git a/blawx/fixtures/workspace/mortality.yaml b/blawx/static/blawx/examples/mortality.yaml similarity index 99% rename from blawx/fixtures/workspace/mortality.yaml rename to blawx/static/blawx/examples/mortality.yaml index d452252f..9f41a3aa 100644 --- a/blawx/fixtures/workspace/mortality.yaml +++ b/blawx/static/blawx/examples/mortality.yaml @@ -1,6 +1,7 @@ - model: blawx.ruledoc pk: 5 fields: + owner: 3 ruledoc_name: Mortality Act rule_text: "Mortality Act\r\n\r\n1. Humans are mortal." scasp_encoding: '' diff --git a/blawx/fixtures/workspace/net30.yaml b/blawx/static/blawx/examples/net30.yaml similarity index 99% rename from blawx/fixtures/workspace/net30.yaml rename to blawx/static/blawx/examples/net30.yaml index 4f0c78d1..8506b718 100644 --- a/blawx/fixtures/workspace/net30.yaml +++ b/blawx/static/blawx/examples/net30.yaml @@ -1,6 +1,7 @@ - model: blawx.ruledoc pk: 8 fields: + owner: 3 ruledoc_name: Net 30 rule_text: "Net Thirty Act\r\n\r\n1. The payment due date of an invoice is 30 days after the date the invoice is issued." diff --git a/blawx/fixtures/workspace/r34.yaml b/blawx/static/blawx/examples/r34.yaml similarity index 99% rename from blawx/fixtures/workspace/r34.yaml rename to blawx/static/blawx/examples/r34.yaml index 9c08542d..b112108b 100644 --- a/blawx/fixtures/workspace/r34.yaml +++ b/blawx/static/blawx/examples/r34.yaml @@ -1,6 +1,7 @@ - model: blawx.ruledoc pk: 4 fields: + owner: 3 ruledoc_name: Rule 34 rule_text: "Legal Profession Professional Conduct Rules\r\n\r\nExecutive appointments\r\n34.\r\n \ (1) A legal practitioner must not accept any executive appointment associated diff --git a/blawx/fixtures/workspace/rps.yaml b/blawx/static/blawx/examples/rps.yaml similarity index 99% rename from blawx/fixtures/workspace/rps.yaml rename to blawx/static/blawx/examples/rps.yaml index 2c2c14e5..aec40084 100644 --- a/blawx/fixtures/workspace/rps.yaml +++ b/blawx/static/blawx/examples/rps.yaml @@ -1,6 +1,7 @@ - model: blawx.ruledoc pk: 2 fields: + owner: 3 ruledoc_name: Rock Paper Scissors Act rule_text: "Rock Paper Scissors Act\n\nPlayers\n1. A game of rock paper scissors has two players.\n2. There are three signs:\n (a) Rock,\n (b) Paper, and\n diff --git a/blawx/fixtures/workspace/siblings.yaml b/blawx/static/blawx/examples/siblings.yaml similarity index 99% rename from blawx/fixtures/workspace/siblings.yaml rename to blawx/static/blawx/examples/siblings.yaml index 4b9bd39a..d86aa0f6 100644 --- a/blawx/fixtures/workspace/siblings.yaml +++ b/blawx/static/blawx/examples/siblings.yaml @@ -1,6 +1,7 @@ - model: blawx.ruledoc pk: 11 fields: + owner: 3 ruledoc_name: Siblings Act rule_text: "Siblings Act\r\n\r\n1. A person's sibling is another person with whom the person shares a parent.\r\n2. With regard to wards of the state, parent diff --git a/blawx/fixtures/workspace/wills.yaml b/blawx/static/blawx/examples/wills.yaml similarity index 99% rename from blawx/fixtures/workspace/wills.yaml rename to blawx/static/blawx/examples/wills.yaml index 12c89e6d..729db1ad 100644 --- a/blawx/fixtures/workspace/wills.yaml +++ b/blawx/static/blawx/examples/wills.yaml @@ -1,6 +1,7 @@ - model: blawx.ruledoc pk: 9 fields: + owner: 3 ruledoc_name: Wills Act rule_text: "Wills Act\r\n\r\n1. A person over the age of 18 may make a will.\r\n2. An active military member over the age of 14 may make a will." diff --git a/blawx/fixtures/workspace/wills_tutorial.yaml b/blawx/static/blawx/examples/wills_tutorial.yaml similarity index 99% rename from blawx/fixtures/workspace/wills_tutorial.yaml rename to blawx/static/blawx/examples/wills_tutorial.yaml index 496acb45..39748b18 100644 --- a/blawx/fixtures/workspace/wills_tutorial.yaml +++ b/blawx/static/blawx/examples/wills_tutorial.yaml @@ -1,6 +1,7 @@ - model: blawx.ruledoc pk: 14 fields: + owner: 3 ruledoc_name: Wills Tutorial rule_text: "Wills Act\r\n\r\n1. A person over the age of 18 may make a will." scasp_encoding: '' diff --git a/blawx/templates/blawx/index.html b/blawx/templates/blawx/index.html index 959e8345..47d36ced 100644 --- a/blawx/templates/blawx/index.html +++ b/blawx/templates/blawx/index.html @@ -2,12 +2,39 @@ {% block header_elements %}