for (LoadAppLogic.CSVFileEntry FileEntry : ReadCSVReadyFileOutput) { // here we assert the PathToFile property of the FileEntryArtifact is the string literal FilePath of the FileEntry object pcf.getContext().addTriple(PC3Utilities.ns("FileEntryArtifact"+iteration), PC3Utilities.ns("PathToFile"), Resource.literal(FileEntry.FilePath)); boolean IsExistsCSVFileOutput = LoadAppLogic.IsExistsCSVFile(FileEntry); // assert the the FileEntryArtifact in this iteration was generated by the Iterator process, where an Iterator process // represent an entire iteration of the body of this loop pcf.assertGeneratedBy(FileEntryArtifacts[iteration], Iterator[iteration], pcf.newRole("csv file"), account); // assert that the Iterator process uses an artifact representing a list of CSV files pcf.assertUsed(Iterator[iteration], ReadCSVReadyFileArtifact, pcf.newRole("list of files", PC3Utilities.ns("role38."+iteration)), account); // here we say that if we are in the first iteration of the loop then the Iterator process was triggered by the // process representing the call to CreateEmptyLoadDB. If we are on the second or third iteration of the loop // we say that the Iterator process was triggered by the final conditional of the previous iteration evaluating // to true. if(iteration == 0) { pcf.assertTriggeredBy(Iterator[iteration], CreateEmptyLoadDBProcess, account); } else { pcf.assertTriggeredBy(Iterator[iteration], IsMatchTableColumnRangesConditionals[iteration-1], account); } // assert that the process representing the call to IsExistsCSVFile used the FileEntryArtifact generated for this loop iteration pcf.assertUsed(IsExistsCSVFileProcesses[iteration], FileEntryArtifacts[iteration], pcf.newRole("csv file metadata", PC3Utilities.ns("role12."+iteration)), account); // assert that the artifact representing the boolean result of the call to IsExistsCSVFile was generated by the process representing the call to IsExistsCSVFile pcf.assertGeneratedBy(IsExistsCSVFileArtifacts[iteration], IsExistsCSVFileProcesses[iteration], pcf.newRole("file metatdata check result", PC3Utilities.ns("role13."+iteration)), account); // assert that the process representing the conditional following a call to IsExistsCSVFile used the artifact generated by the process representing the call to IsExistsCSVFile. // Note that we record the time we observed this event to facilitate answering optional query 3. pcf.assertUsed(IsExistsCSVFileConditionals[iteration], IsExistsCSVFileArtifacts[iteration], pcf.newRole("boolean input", PC3Utilities.ns("role14."+iteration)), account, new ObservedTime(new Date())); if (!IsExistsCSVFileOutput ) { throw new RuntimeException("IsExistsCSVFile failed"); } // if we reached this line in the code the conditional preceeding it passed. Therefore, assert that the process representing the next call to be made (ReadCSVFileColumnNames), // was triggered by the process representing the conditional. pcf.assertTriggeredBy(ReadCSVFileColumnNamesProcesses[iteration], IsExistsCSVFileConditionals[iteration], account); // . . . Omitted code, since approach is exactly the same as above for these events. . . // boolean IsMatchTableColumnRangesOutput = LoadAppLogic.IsMatchTableColumnRanges(CreateEmptyLoadDBOutput, ReadCSVFileColumnNamesOutput); // assert that the process representing the call to IsMatchTableColumnRanges used the artifact representing the result of the call to CreateEmptyLoadDB (the connection params). pcf.assertUsed(IsMatchTableColumnRangesProcesses[iteration], CreateEmptyLoadDBArtifact, pcf.newRole("database connection params", PC3Utilities.ns("role32."+iteration)), account); // assert that the process representing the call to IsMatchTableColumnRanges used the artifact representing the list of CSV file column names pcf.assertUsed(IsMatchTableColumnRangesProcesses[iteration], ReadCSVFileColumnNamesArtifacts[iteration], pcf.newRole("target table name and column ranges", PC3Utilities.ns("role33."+iteration)), account); // assert that the artifact representing the boolean result of a call to IsMatchTableColumnRanges was generated by the process representing the call to // IsMatchTableColumnRanges pcf.assertGeneratedBy(IsMatchTableColumnRangesArtifacts[iteration], IsMatchTableColumnRangesProcesses[iteration], pcf.newRole("column range check result", PC3Utilities.ns("role34."+iteration)), account); // assert that the process representing the conditional which follows a call to IsMatchTableColumnRanges used the artifact representing the boolean result of a call to // IsMatchTableColumnRanges pcf.assertUsed(IsMatchTableColumnRangesConditionals[iteration], IsMatchTableColumnRangesArtifacts[iteration], pcf.newRole("boolean input", PC3Utilities.ns("role35."+iteration)), account); // 7.m. Control Flow: Decision if (!IsMatchTableColumnRangesOutput ) { throw new RuntimeException("IsMatchTableColumnRanges failed"); } String filePath = FileEntry.FilePath; // assert that the process representing the conditional following IsMatchTableColumnRanges has a "PerformedOn" property, which represents the table name // that IsMatchTableColumnRanges was checked against. This property has a string literal value described by a substring of the FileEntry object's FilePath variable // defined between the indices of last occurance of characer "_" and ".". This observation facilitated answering core query 2. pcf.getContext().addTriple(PC3Utilities.ns("IsMatchTableColumnRangesConditionals"+iteration), PC3Utilities.ns("PerformedOn"), Resource.literal(filePath.substring(filePath.lastIndexOf("_")+1, filePath.lastIndexOf(".")))); iteration++; }