Compare commits

..

17 Commits

Author SHA1 Message Date
maverickstuder
8126e7f81e RED-10200: refactoring and cleanup 2024-12-02 18:18:13 +01:00
maverickstuder
af347de8a3 RED-10200: Spike performant rules update logic 2024-12-02 16:08:39 +01:00
maverickstuder
dfd958466e RED-10200: Spike performant rules update logic 2024-12-02 15:20:17 +01:00
maverickstuder
ac384f0636 RED-10200: Spike performant rules update logic 2024-12-02 13:32:54 +01:00
maverickstuder
29d25d432c RED-10200: Spike performant rules update logic 2024-12-02 12:25:36 +01:00
maverickstuder
3a9bd3958e RED-10200: Spike performant rules update logic 2024-12-02 12:02:03 +01:00
maverickstuder
104496c3cc RED-10200: Spike: Performant update logic for facts in working memory 2024-12-02 11:35:24 +01:00
maverickstuder
16b4910ffb Merge branch 'master' into RED-10200-2 2024-12-02 11:03:29 +01:00
maverickstuder
a93049cd41 RED-10200: Spike performant rules update logic 2024-12-02 10:54:28 +01:00
maverickstuder
a36aa0c047 Merge remote-tracking branch 'origin/RED-10200-2' into RED-10200-2 2024-12-02 10:18:09 +01:00
maverickstuder
ca9dcc8550 RED-10200: Spike performant rules update logic 2024-12-02 10:18:02 +01:00
maverickstuder
7bb97c1027 RED-10200: Spike: Performant update logic for facts in working memory 2024-11-29 16:17:49 +01:00
maverickstuder
27b5a1afcd RED-10200: Spike: Performant update logic for facts in working memory 2024-11-29 15:06:35 +01:00
maverickstuder
d34921acd8 RED-10200: Spike: Performant update logic for facts in working memory 2024-11-28 09:23:26 +01:00
maverickstuder
3429563079 Merge remote-tracking branch 'origin/RED-10200-2' into RED-10200-2
# Conflicts:
#	redaction-service-v1/document/src/main/java/com/iqser/red/service/redaction/v1/server/model/document/entity/TextEntity.java
#	redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/drools/EntityDroolsExecutionService.java
#	redaction-service-v1/redaction-service-server-v1/src/test/java/com/iqser/red/service/redaction/v1/server/AnalysisEnd2EndTest.java
2024-11-26 15:50:16 +01:00
maverickstuder
00d83f58fd RED-10200: stuff, comments, and more stuff, and even more comments 2024-11-26 15:40:24 +01:00
maverickstuder
035756678f RED-10200: Spike: Performant update logic for facts in working memory 2024-11-26 12:44:31 +01:00
33 changed files with 229 additions and 481 deletions

View File

@ -9,7 +9,9 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Stream; import java.util.stream.Stream;
import com.iqser.red.service.redaction.v1.server.model.document.entity.EntityType; import com.iqser.red.service.redaction.v1.server.model.document.entity.Containment;
import com.iqser.red.service.redaction.v1.server.model.document.entity.Equality;
import com.iqser.red.service.redaction.v1.server.model.document.entity.Intersection;
import com.iqser.red.service.redaction.v1.server.model.document.entity.TextEntity; import com.iqser.red.service.redaction.v1.server.model.document.entity.TextEntity;
import com.iqser.red.service.redaction.v1.server.model.document.nodes.Document; import com.iqser.red.service.redaction.v1.server.model.document.nodes.Document;
import com.iqser.red.service.redaction.v1.server.model.document.nodes.GenericSemanticNode; import com.iqser.red.service.redaction.v1.server.model.document.nodes.GenericSemanticNode;
@ -371,13 +373,23 @@ public class DocumentTree {
EntityCreationUtility.addToPages(entity); EntityCreationUtility.addToPages(entity);
EntityCreationUtility.addEntityToNodeEntitySets(entity); EntityCreationUtility.addEntityToNodeEntitySets(entity);
for (TextEntity textEntity : entity.getDeepestFullyContainingNode().getEntities()) {
if (entity.getEntityType().equals(EntityType.TEMPORARY)) { if (entity.intersects(textEntity) && !entity.equals(textEntity)) {
return; if (textEntity.getTextRange().equals(entity.getTextRange())) {
textEntity.getRelations().put(textEntity, new Equality(entity, textEntity));
entity.getRelations().put(textEntity, new Equality(textEntity, entity));
} else if (textEntity.containedBy(entity)) {
entity.getRelations().put(textEntity, new Containment(entity, textEntity));
textEntity.getRelations().put(entity, new Intersection(textEntity, entity));
} else if (entity.containedBy(textEntity)) {
textEntity.getRelations().put(entity, new Containment(textEntity, entity));
entity.getRelations().put(textEntity, new Intersection(entity, textEntity));
} else {
entity.getRelations().put(textEntity, new Intersection(entity, textEntity));
textEntity.getRelations().put(entity, new Intersection(textEntity, entity));
}
}
} }
entity.computeRelations();
entity.notifyEntityInserted();
} }

View File

@ -10,11 +10,4 @@ public abstract class AbstractRelation implements Relation {
protected final TextEntity a; protected final TextEntity a;
protected final TextEntity b; protected final TextEntity b;
@Override
public String toString() {
return this.getClass().getSimpleName() + "{" + "a=" + a + ", b=" + b + '}';
}
} }

View File

@ -6,6 +6,5 @@ public enum EntityType {
RECOMMENDATION, RECOMMENDATION,
FALSE_POSITIVE, FALSE_POSITIVE,
FALSE_RECOMMENDATION, FALSE_RECOMMENDATION,
DICTIONARY_REMOVAL, DICTIONARY_REMOVAL
TEMPORARY
} }

View File

@ -367,13 +367,6 @@ public interface IEntity {
void removeEntityEventListener(EntityEventListener listener); void removeEntityEventListener(EntityEventListener listener);
default void notifyEntityInserted() {
for (EntityEventListener listener : getEntityEventListeners()) {
listener.onEntityInserted(this);
}
}
default void notifyEntityUpdated() { default void notifyEntityUpdated() {
for (EntityEventListener listener : getEntityEventListeners()) { for (EntityEventListener listener : getEntityEventListeners()) {

View File

@ -47,7 +47,7 @@ public class TextEntity implements IEntity {
TextRange textRange; TextRange textRange;
@Builder.Default @Builder.Default
Set<TextRange> duplicateTextRanges = new HashSet<>(); List<TextRange> duplicateTextRanges = new ArrayList<>();
String type; // TODO: make final once ManualChangesApplicationService::recategorize is deleted String type; // TODO: make final once ManualChangesApplicationService::recategorize is deleted
final EntityType entityType; final EntityType entityType;
@ -74,7 +74,7 @@ public class TextEntity implements IEntity {
SemanticNode deepestFullyContainingNode; SemanticNode deepestFullyContainingNode;
@Builder.Default @Builder.Default
Map<TextEntity, Set<Relation>> relations = new HashMap<>(); Map<TextEntity, Relation> relations = new HashMap<>();
@Builder.Default @Builder.Default
Collection<EntityEventListener> entityEventListeners = new ArrayList<>(); Collection<EntityEventListener> entityEventListeners = new ArrayList<>();
@ -174,7 +174,7 @@ public class TextEntity implements IEntity {
pages.forEach(page -> page.getEntities().remove(this)); pages.forEach(page -> page.getEntities().remove(this));
intersectingNodes = new LinkedList<>(); intersectingNodes = new LinkedList<>();
relations.keySet() relations.keySet()
.forEach(entity -> entity.getRelations().remove(this)); .forEach(entity -> entity.relations.remove(this));
relations = new HashedMap<>(); relations = new HashedMap<>();
deepestFullyContainingNode = null; deepestFullyContainingNode = null;
pages = new HashSet<>(); pages = new HashSet<>();
@ -215,20 +215,22 @@ public class TextEntity implements IEntity {
return textEntity.contains(this); return textEntity.contains(this);
} }
public boolean contains(TextEntity textEntity) { public boolean contains(TextEntity textEntity) {
if (this.textRange.contains(textEntity.getTextRange())) { if (this.textRange.contains(textEntity.getTextRange())) {
return true; return true;
} }
Set<TextRange> textEntityDuplicateRanges = textEntity.getDuplicateTextRanges(); List<TextRange> textEntityDuplicateRanges = textEntity.getDuplicateTextRanges();
// use optimized indexed loops for extra performance boost
for (TextRange duplicateTextRange : this.duplicateTextRanges) { for (int i = 0, duplicateTextRangesSize = duplicateTextRanges.size(); i < duplicateTextRangesSize; i++) {
TextRange duplicateTextRange = duplicateTextRanges.get(i);
if (duplicateTextRange.contains(textEntity.getTextRange())) { if (duplicateTextRange.contains(textEntity.getTextRange())) {
return true; return true;
} }
for (int j = 0, textEntityDuplicateRangesSize = textEntityDuplicateRanges.size(); j < textEntityDuplicateRangesSize; j++) {
for (TextRange otherRange : textEntityDuplicateRanges) { TextRange otherRange = textEntityDuplicateRanges.get(j);
if (duplicateTextRange.contains(otherRange)) { if (duplicateTextRange.contains(otherRange)) {
return true; return true;
} }
@ -239,7 +241,6 @@ public class TextEntity implements IEntity {
} }
public boolean intersects(TextEntity textEntity) { public boolean intersects(TextEntity textEntity) {
return this.textRange.intersects(textEntity.getTextRange()) // return this.textRange.intersects(textEntity.getTextRange()) //
@ -338,7 +339,6 @@ public class TextEntity implements IEntity {
.orElse(getMatchedRule().isWriteValueWithLineBreaks() ? getValueWithLineBreaks() : value); .orElse(getMatchedRule().isWriteValueWithLineBreaks() ? getValueWithLineBreaks() : value);
} }
@Override @Override
public void addEntityEventListener(EntityEventListener listener) { public void addEntityEventListener(EntityEventListener listener) {
@ -353,27 +353,4 @@ public class TextEntity implements IEntity {
} }
public void computeRelations() {
for (TextEntity textEntity : this.getDeepestFullyContainingNode().getEntities()) {
if (this.intersects(textEntity) && !this.equals(textEntity) && !textEntity.getEntityType().equals(EntityType.TEMPORARY)) {
if (textEntity.getTextRange().equals(this.getTextRange())) {
textEntity.getRelations().computeIfAbsent(this, k -> new HashSet<>()).add(new Equality(this, textEntity));
this.getRelations().computeIfAbsent(textEntity, k -> new HashSet<>()).add(new Equality(textEntity, this));
} else if (textEntity.containedBy(this)) {
textEntity.getRelations().computeIfAbsent(this, k -> new HashSet<>()).add(new Intersection(textEntity, this));
this.getRelations().computeIfAbsent(textEntity, k -> new HashSet<>()).add(new Containment(this, textEntity));
} else if (this.containedBy(textEntity)) {
textEntity.getRelations().computeIfAbsent(this, k -> new HashSet<>()).add(new Containment(textEntity, this));
this.getRelations().computeIfAbsent(textEntity, k -> new HashSet<>()).add(new Intersection(this, textEntity));
} else {
textEntity.getRelations().computeIfAbsent(this, k -> new HashSet<>()).add(new Intersection(textEntity, this));
this.getRelations().computeIfAbsent(textEntity, k -> new HashSet<>()).add(new Intersection(this, textEntity));
}
}
}
}
} }

View File

@ -16,7 +16,7 @@ val layoutParserVersion = "0.193.0"
val jacksonVersion = "2.15.2" val jacksonVersion = "2.15.2"
val droolsVersion = "9.44.0.Final" val droolsVersion = "9.44.0.Final"
val pdfBoxVersion = "3.0.0" val pdfBoxVersion = "3.0.0"
val persistenceServiceVersion = "2.641.0" val persistenceServiceVersion = "2.639.0"
val llmServiceVersion = "1.20.0-RED10072.2" val llmServiceVersion = "1.20.0-RED10072.2"
val springBootStarterVersion = "3.1.5" val springBootStarterVersion = "3.1.5"
val springCloudVersion = "4.0.4" val springCloudVersion = "4.0.4"
@ -77,8 +77,8 @@ dependencies {
implementation("org.apache.tomcat:tomcat-websocket:${tomcatVersion}") implementation("org.apache.tomcat:tomcat-websocket:${tomcatVersion}")
implementation("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}") implementation("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
implementation("org.liquibase:liquibase-core:4.29.2") // Needed to be set explicit, otherwise spring dependency management sets it to 4.20.0 implementation("org.liquibase:liquibase-core:4.30.0") // Needed to be set explicit, otherwise spring dependency management sets it to 4.20.0
implementation("org.liquibase.ext:liquibase-mongodb:4.29.2") implementation("org.apache.commons:commons-lang3:3.13.0") // Needed for liquibase 4.30.0
implementation("net.logstash.logback:logstash-logback-encoder:7.4") implementation("net.logstash.logback:logstash-logback-encoder:7.4")
api("ch.qos.logback:logback-classic") api("ch.qos.logback:logback-classic")

View File

@ -181,7 +181,7 @@ public class EntityFindingUtility {
return textBlocks.stream() return textBlocks.stream()
.flatMap(searchImplementation::getBoundaries) .flatMap(searchImplementation::getBoundaries)
.map(boundary -> entityCreationService.byTextRangeWithEngine(boundary, "temp", EntityType.TEMPORARY, node, Collections.emptySet())) .map(boundary -> entityCreationService.byTextRangeWithEngine(boundary, "temp", EntityType.ENTITY, node, Collections.emptySet()))
.filter(Optional::isPresent) .filter(Optional::isPresent)
.map(Optional::get) .map(Optional::get)
.distinct() .distinct()
@ -208,7 +208,7 @@ public class EntityFindingUtility {
return textBlocks.stream() return textBlocks.stream()
.flatMap(tb -> searchImplementation.getBoundaries(tb) .flatMap(tb -> searchImplementation.getBoundaries(tb)
.filter(textRange -> entityCreationService.isValidEntityTextRange(tb, textRange))) .filter(textRange -> entityCreationService.isValidEntityTextRange(tb, textRange)))
.map(boundary -> entityCreationService.byTextRangeWithEngine(boundary, "temp", EntityType.TEMPORARY, document, Collections.emptySet())) .map(boundary -> entityCreationService.byTextRangeWithEngine(boundary, "temp", EntityType.ENTITY, document, Collections.emptySet()))
.filter(Optional::isPresent) .filter(Optional::isPresent)
.map(Optional::get) .map(Optional::get)
.distinct() .distinct()
@ -222,7 +222,7 @@ public class EntityFindingUtility {
return searchImplementation.getBoundaries(document.getTextBlock()) return searchImplementation.getBoundaries(document.getTextBlock())
.filter(textRange -> entityCreationService.isValidEntityTextRange(document.getTextBlock(), textRange)) .filter(textRange -> entityCreationService.isValidEntityTextRange(document.getTextBlock(), textRange))
.map(boundary -> entityCreationService.byTextRangeWithEngine(boundary, "temp", EntityType.TEMPORARY, document, Collections.emptySet())) .map(boundary -> entityCreationService.byTextRangeWithEngine(boundary, "temp", EntityType.ENTITY, document, Collections.emptySet()))
.filter(Optional::isPresent) .filter(Optional::isPresent)
.map(Optional::get) .map(Optional::get)
.distinct() .distinct()

View File

@ -431,7 +431,7 @@ public class EntityLogCreatorService {
private static EntryType getEntryType(EntityType entityType) { private static EntryType getEntryType(EntityType entityType) {
return switch (entityType) { return switch (entityType) {
case ENTITY, TEMPORARY -> EntryType.ENTITY; case ENTITY -> EntryType.ENTITY;
case HINT -> EntryType.HINT; case HINT -> EntryType.HINT;
case FALSE_POSITIVE, DICTIONARY_REMOVAL -> EntryType.FALSE_POSITIVE; case FALSE_POSITIVE, DICTIONARY_REMOVAL -> EntryType.FALSE_POSITIVE;
case RECOMMENDATION -> EntryType.RECOMMENDATION; case RECOMMENDATION -> EntryType.RECOMMENDATION;

View File

@ -3,7 +3,6 @@ package com.iqser.red.service.redaction.v1.server.service;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -80,8 +79,6 @@ public class ManualChangesApplicationService {
@Deprecated @Deprecated
public void resizeEntityAndReinsert(TextEntity entityToBeResized, ManualResizeRedaction manualResizeRedaction) { public void resizeEntityAndReinsert(TextEntity entityToBeResized, ManualResizeRedaction manualResizeRedaction) {
entityToBeResized.notifyEntityRemoved();
PositionOnPage positionOnPageToBeResized = entityToBeResized.getPositionsOnPagePerPage() PositionOnPage positionOnPageToBeResized = entityToBeResized.getPositionsOnPagePerPage()
.stream() .stream()
.filter(redactionPosition -> redactionPosition.getId().equals(manualResizeRedaction.getAnnotationId())) .filter(redactionPosition -> redactionPosition.getId().equals(manualResizeRedaction.getAnnotationId()))
@ -93,7 +90,7 @@ public class ManualChangesApplicationService {
.map(ManualChangesApplicationService::toRectangle2D) .map(ManualChangesApplicationService::toRectangle2D)
.collect(Collectors.toList())); .collect(Collectors.toList()));
entityToBeResized.getManualOverwrite().addChange(manualResizeRedaction); entityToBeResized.addManualChange(manualResizeRedaction);
SemanticNode node = entityToBeResized.getDeepestFullyContainingNode(); SemanticNode node = entityToBeResized.getDeepestFullyContainingNode();
PrecursorEntity searchEntity = PrecursorEntity.fromManualResizeRedaction(manualResizeRedaction); PrecursorEntity searchEntity = PrecursorEntity.fromManualResizeRedaction(manualResizeRedaction);
@ -109,7 +106,7 @@ public class ManualChangesApplicationService {
.stream() .stream()
.flatMap(Collection::stream) .flatMap(Collection::stream)
.forEach(TextEntity::removeFromGraph); .forEach(TextEntity::removeFromGraph);
break; return;
} }
possibleEntities.values() possibleEntities.values()
@ -120,15 +117,9 @@ public class ManualChangesApplicationService {
if (node.hasParent()) { if (node.hasParent()) {
node = node.getParent(); node = node.getParent();
} else { } else {
node = null; break;
} }
} }
entityToBeResized.getRelations().keySet()
.forEach(textEntity -> textEntity.getRelations().remove(entityToBeResized));
entityToBeResized.setRelations(new HashMap<>());
entityToBeResized.computeRelations();
entityToBeResized.notifyEntityInserted();
} }
@ -155,7 +146,7 @@ public class ManualChangesApplicationService {
entityToBeResized.setTextRange(closestEntity.getTextRange()); entityToBeResized.setTextRange(closestEntity.getTextRange());
entityToBeResized.setTextAfter(closestEntity.getTextAfter()); entityToBeResized.setTextAfter(closestEntity.getTextAfter());
entityToBeResized.setTextBefore(closestEntity.getTextBefore()); entityToBeResized.setTextBefore(closestEntity.getTextBefore());
entityToBeResized.setDuplicateTextRanges(new HashSet<>(closestEntity.getDuplicateTextRanges())); entityToBeResized.setDuplicateTextRanges(new ArrayList<>(closestEntity.getDuplicateTextRanges()));
entityToBeResized.setValue(closestEntity.getValue()); entityToBeResized.setValue(closestEntity.getValue());
entityToBeResized.setPages(newIntersectingPages); entityToBeResized.setPages(newIntersectingPages);
} }

View File

@ -985,18 +985,17 @@ public class EntityCreationService {
return Optional.empty(); // Entity has been recategorized and should not be created at all. return Optional.empty(); // Entity has been recategorized and should not be created at all.
} }
TextEntity existingEntity = optionalTextEntity.get(); TextEntity existingEntity = optionalTextEntity.get();
if (existingEntity.getTextRange().equals(trimmedTextRange)) { if (existingEntity.getTextRange().equals(textRange)) {
return optionalTextEntity; // exactly the same entity, return directly return optionalTextEntity; // exactly the same entity, return directly
} }
if (!existingEntity.resized()) { if (!existingEntity.resized()) {
addDuplicateEntityToGraph(existingEntity, trimmedTextRange, node); addDuplicateEntityToGraph(existingEntity, textRange, node);
return optionalTextEntity; // If Entity has not been resized, insert as duplicate at appropriate position return optionalTextEntity; // If Entity has not been resized, insert as duplicate at appropriate position
} }
return Optional.empty(); // Entity has been resized, if there are duplicates they should be treated there return Optional.empty(); // Entity has been resized, if there are duplicates they should be treated there
} }
addListenerToEntity(entity);
node.getDocumentTree().addEntityToGraph(entity); node.getDocumentTree().addEntityToGraph(entity);
insertToKieSession(entity);
entity.addEngines(engines); entity.addEngines(engines);
@ -1422,8 +1421,8 @@ public class EntityCreationService {
.ifPresent(e -> addDuplicateEntityToGraph(e, entity.getTextRange(), node)); .ifPresent(e -> addDuplicateEntityToGraph(e, entity.getTextRange(), node));
} else { } else {
addListenerToEntity(entity);
documentTree.addEntityToGraph(entity); documentTree.addEntityToGraph(entity);
insertToKieSession(entity);
} }
} }
@ -1475,13 +1474,18 @@ public class EntityCreationService {
} }
private void addListenerToEntity(TextEntity textEntity) {
/**
* Inserts a text entity into the kieSession for further processing.
*
* @param textEntity The merged text entity to insert.
*/
public void insertToKieSession(TextEntity textEntity) {
if(kieSessionUpdater != null) { if(kieSessionUpdater != null) {
textEntity.addEntityEventListener(kieSessionUpdater); kieSessionUpdater.insert(textEntity);
} }
} }
} }

View File

@ -14,15 +14,12 @@ import org.springframework.stereotype.Service;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Engine; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Engine;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.imported.ImportedRedactions; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.imported.ImportedRedactions;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualRedactions; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualRedactions;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Rectangle;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.BaseAnnotation; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.BaseAnnotation;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.IdRemoval; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.IdRemoval;
import com.iqser.red.service.redaction.v1.server.RedactionServiceSettings; import com.iqser.red.service.redaction.v1.server.RedactionServiceSettings;
import com.iqser.red.service.redaction.v1.server.model.PrecursorEntity; import com.iqser.red.service.redaction.v1.server.model.PrecursorEntity;
import com.iqser.red.service.redaction.v1.server.model.document.entity.EntityType; import com.iqser.red.service.redaction.v1.server.model.document.entity.EntityType;
import com.iqser.red.service.redaction.v1.server.model.document.entity.TextEntity; import com.iqser.red.service.redaction.v1.server.model.document.entity.TextEntity;
import com.iqser.red.service.redaction.v1.server.model.document.nodes.Document;
import com.iqser.red.service.redaction.v1.server.model.document.nodes.Page;
import com.iqser.red.service.redaction.v1.server.model.document.nodes.SemanticNode; import com.iqser.red.service.redaction.v1.server.model.document.nodes.SemanticNode;
import com.iqser.red.service.redaction.v1.server.service.DictionaryService; import com.iqser.red.service.redaction.v1.server.service.DictionaryService;
import com.iqser.red.service.redaction.v1.server.service.EntityFindingUtility; import com.iqser.red.service.redaction.v1.server.service.EntityFindingUtility;
@ -44,14 +41,9 @@ public class EntityFromPrecursorCreationService {
RedactionServiceSettings settings; RedactionServiceSettings settings;
public List<PrecursorEntity> createEntitiesIfFoundAndReturnNotFoundEntries(ManualRedactions manualRedactions, Document document, String dossierTemplateId) { public List<PrecursorEntity> createEntitiesIfFoundAndReturnNotFoundEntries(ManualRedactions manualRedactions, SemanticNode node, String dossierTemplateId) {
Set<Integer> pageNumbers = document.getPages()
.stream()
.map(Page::getNumber)
.collect(Collectors.toSet());
Set<IdRemoval> idRemovals = manualRedactions.getIdsToRemove(); Set<IdRemoval> idRemovals = manualRedactions.getIdsToRemove();
List<PrecursorEntity> manualEntities = manualRedactions.getEntriesToAdd() List<PrecursorEntity> manualEntities = manualRedactions.getEntriesToAdd()
.stream() .stream()
.filter(BaseAnnotation::isLocal) .filter(BaseAnnotation::isLocal)
@ -60,10 +52,6 @@ public class EntityFromPrecursorCreationService {
.filter(idRemoval -> idRemoval.getRequestDate().isAfter(manualRedactionEntry.getRequestDate())) .filter(idRemoval -> idRemoval.getRequestDate().isAfter(manualRedactionEntry.getRequestDate()))
.findAny()// .findAny()//
.isEmpty()) .isEmpty())
.filter(manualRedactionEntry -> manualRedactionEntry.getPositions()
.stream()
.map(Rectangle::getPage)
.allMatch(pageNumbers::contains))
.map(manualRedactionEntry -> // .map(manualRedactionEntry -> //
PrecursorEntity.fromManualRedactionEntry(manualRedactionEntry, dictionaryService.isHint(manualRedactionEntry.getType(), dossierTemplateId))) PrecursorEntity.fromManualRedactionEntry(manualRedactionEntry, dictionaryService.isHint(manualRedactionEntry.getType(), dossierTemplateId)))
.peek(manualEntity -> { .peek(manualEntity -> {
@ -74,7 +62,7 @@ public class EntityFromPrecursorCreationService {
} }
}) })
.toList(); .toList();
return toTextEntity(manualEntities, document); return toTextEntity(manualEntities, node);
} }
@ -152,7 +140,7 @@ public class EntityFromPrecursorCreationService {
} }
correctEntity.setDeepestFullyContainingNode(closestEntity.getDeepestFullyContainingNode()); correctEntity.setDeepestFullyContainingNode(closestEntity.getDeepestFullyContainingNode());
correctEntity.setIntersectingNodes(new ArrayList<>(closestEntity.getIntersectingNodes())); correctEntity.setIntersectingNodes(new ArrayList<>(closestEntity.getIntersectingNodes()));
correctEntity.setDuplicateTextRanges(new HashSet<>(closestEntity.getDuplicateTextRanges())); correctEntity.setDuplicateTextRanges(new ArrayList<>(closestEntity.getDuplicateTextRanges()));
correctEntity.setPages(new HashSet<>(closestEntity.getPages())); correctEntity.setPages(new HashSet<>(closestEntity.getPages()));
correctEntity.setValue(closestEntity.getValue()); correctEntity.setValue(closestEntity.getValue());

View File

@ -28,7 +28,7 @@ import com.iqser.red.service.redaction.v1.server.logger.RulesLogger;
import com.iqser.red.service.redaction.v1.server.logger.TrackingAgendaEventListener; import com.iqser.red.service.redaction.v1.server.logger.TrackingAgendaEventListener;
import com.iqser.red.service.redaction.v1.server.model.NerEntities; import com.iqser.red.service.redaction.v1.server.model.NerEntities;
import com.iqser.red.service.redaction.v1.server.model.dictionary.Dictionary; import com.iqser.red.service.redaction.v1.server.model.dictionary.Dictionary;
import com.iqser.red.service.redaction.v1.server.model.document.entity.TextEntity; import com.iqser.red.service.redaction.v1.server.model.document.entity.IEntity;
import com.iqser.red.service.redaction.v1.server.model.document.nodes.Document; import com.iqser.red.service.redaction.v1.server.model.document.nodes.Document;
import com.iqser.red.service.redaction.v1.server.model.document.nodes.Image; import com.iqser.red.service.redaction.v1.server.model.document.nodes.Image;
import com.iqser.red.service.redaction.v1.server.model.document.nodes.SemanticNode; import com.iqser.red.service.redaction.v1.server.model.document.nodes.SemanticNode;
@ -121,17 +121,14 @@ public class EntityDroolsExecutionService {
.flatMap(SemanticNode::streamAllSubNodes) .flatMap(SemanticNode::streamAllSubNodes)
.forEach(semanticNode -> { .forEach(semanticNode -> {
if (semanticNode instanceof Image image) { if (semanticNode instanceof Image image) {
image.addEntityEventListener(kieSessionUpdater); kieSessionUpdater.insert(image);
image.notifyEntityInserted();
} else { } else {
kieSession.insert(semanticNode); kieSession.insert(semanticNode);
} }
}); });
for (TextEntity textEntity : document.getEntities()) { document.getEntities()
textEntity.addEntityEventListener(kieSessionUpdater); .forEach(kieSessionUpdater::insert);
textEntity.notifyEntityInserted();
}
document.getPages() document.getPages()
.forEach(kieSession::insert); .forEach(kieSession::insert);

View File

@ -1,9 +1,5 @@
package com.iqser.red.service.redaction.v1.server.service.drools; package com.iqser.red.service.redaction.v1.server.service.drools;
import java.util.Collection;
import java.util.Collections;
import java.util.function.Consumer;
import org.kie.api.runtime.KieSession; import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.rule.FactHandle; import org.kie.api.runtime.rule.FactHandle;
@ -24,10 +20,23 @@ public class KieSessionUpdater implements EntityEventListener {
KieSession kieSession; KieSession kieSession;
public void insert(IEntity entity) {
entity.addEntityEventListener(this);
onEntityInserted(entity);
}
@Override @Override
public void onEntityInserted(IEntity entity) { public void onEntityInserted(IEntity entity) {
handleOnEntityEvent(entity, kieSession::insert); if (entity instanceof TextEntity textEntity) {
updateIntersectingNodes(textEntity);
textEntity.getRelations().values()
.forEach(kieSession::insert);
textEntity.getRelations().keySet()
.forEach(k -> kieSession.insert(k.getRelations()
.get(textEntity)));
}
kieSession.insert(entity); kieSession.insert(entity);
} }
@ -35,32 +44,14 @@ public class KieSessionUpdater implements EntityEventListener {
@Override @Override
public void onEntityUpdated(IEntity entity) { public void onEntityUpdated(IEntity entity) {
handleOnEntityEvent(entity, this::updateFactIfPresent);
kieSession.update(kieSession.getFactHandle(entity), entity);
}
@Override
public void onEntityRemoved(IEntity entity) {
handleOnEntityEvent(entity, this::deleteFactIfPresent);
kieSession.delete(kieSession.getFactHandle(entity));
}
private void handleOnEntityEvent(IEntity entity, Consumer<Object> consumer) {
if (entity instanceof TextEntity textEntity) { if (entity instanceof TextEntity textEntity) {
updateIntersectingNodes(textEntity); updateIntersectingNodes(textEntity);
textEntity.getRelations().values() textEntity.getRelations().values()
.stream() .forEach(this::updateFactIfPresent);
.flatMap(Collection::stream)
.forEach(consumer);
textEntity.getRelations().keySet() textEntity.getRelations().keySet()
.forEach(k -> k.getRelations().getOrDefault(textEntity, Collections.emptySet()) .forEach(k -> updateFactIfPresent(k.getRelations()
.forEach(consumer)); .get(textEntity)));
} }
if (entity instanceof Image image) { if (entity instanceof Image image) {
SemanticNode parent = image; SemanticNode parent = image;
while (parent.hasParent()) { while (parent.hasParent()) {
@ -68,6 +59,29 @@ public class KieSessionUpdater implements EntityEventListener {
kieSession.update(kieSession.getFactHandle(parent), parent); kieSession.update(kieSession.getFactHandle(parent), parent);
} }
} }
kieSession.update(kieSession.getFactHandle(entity), entity);
}
@Override
public void onEntityRemoved(IEntity entity) {
if (entity instanceof TextEntity textEntity) {
updateIntersectingNodes(textEntity);
textEntity.getRelations().values()
.forEach(this::deleteFactIfPresent);
textEntity.getRelations().keySet()
.forEach(k -> deleteFactIfPresent(k.getRelations()
.get(textEntity)));
}
if (entity instanceof Image image) {
SemanticNode parent = image;
while (parent.hasParent()) {
parent = parent.getParent();
kieSession.update(kieSession.getFactHandle(parent), parent);
}
}
kieSession.delete(kieSession.getFactHandle(entity));
} }

View File

@ -25,8 +25,7 @@ fforesight:
ignored-endpoints: [ '/redaction-gateway-v1', '/actuator/health/**',"/api/rules-logging/rulesocket","/api/rules-logging/rulesocket/**", '/redaction-gateway-v1/async/download/with-ott/**', ignored-endpoints: [ '/redaction-gateway-v1', '/actuator/health/**',"/api/rules-logging/rulesocket","/api/rules-logging/rulesocket/**", '/redaction-gateway-v1/async/download/with-ott/**',
'/internal-api/**', '/redaction-gateway-v1/docs/swagger-ui', '/rules/test', '/internal-api/**', '/redaction-gateway-v1/docs/swagger-ui', '/rules/test',
'/redaction-gateway-v1/docs/**','/redaction-gateway-v1/docs', '/redaction-gateway-v1/docs/**','/redaction-gateway-v1/docs',
'/api', '/api/','/api/docs/**','/api/docs','/api/docs/swagger-ui', '/api', '/api/','/api/docs/**','/api/docs','/api/docs/swagger-ui' ]
'/actuator/prometheus' ]
spring: spring:
application: application:

View File

@ -1437,7 +1437,7 @@ rule "MAN.4.1: Apply legal basis change"
//------------------------------------ Entity merging rules ------------------------------------ //------------------------------------ Entity merging rules ------------------------------------
// Rule unit: X.0 // Rule unit: X.0
rule "X.0.0: Remove Entity contained by Entity of same type" rule "X.0.0: Remove Container Entity Contained by Container of Same Type"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -1462,7 +1462,7 @@ rule "X.0.0: Remove Entity contained by Entity of same type"
$contained.remove("X.0.0", "remove Entity contained by Entity of same type"); $contained.remove("X.0.0", "remove Entity contained by Entity of same type");
end end
rule "X.0.1: Remove Entity contained by Entity of same type with manual changes" rule "X.0.1: Remove Container and Contained Entities with Manual Changes"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -1482,7 +1482,7 @@ end
// Rule unit: X.2 // Rule unit: X.2
rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE" rule "X.2.0: Remove ENTITY and FALSE_POSITIVE Containing It"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -1498,7 +1498,7 @@ rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE"
$contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE"); $contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE");
end end
rule "X.2.1: Remove Entity of type HINT when contained by FALSE_POSITIVE" rule "X.2.1: Remove HINT Contained by FALSE_POSITIVE"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -1567,7 +1567,7 @@ rule "X.5.0: Remove Entity of type RECOMMENDATION when intersected by ENTITY"
$b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY"); $b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY");
end end
rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATION" rule "X.5.1: Remove Lower Priority RECOMMENDATION Contained by Higher Priority RECOMMENDATION"
salience 256 salience 256
when when
$containment: Containment( $containment: Containment(
@ -1584,23 +1584,6 @@ rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATI
end end
rule "X.5.2: Remove Entity of type RECOMMENDATION when contained by ENTITY of same type"
salience 256
when
$intersection: Containment(
$container: container,
$contained: contained,
($container.entityType == EntityType.ENTITY || $container.entityType == EntityType.HINT),
!$container.removed(),
$contained.entityType == EntityType.RECOMMENDATION,
$container.type() == $contained.type(),
!$contained.hasManualChanges()
)
then
$contained.remove("X.5.2", "remove Entity of type RECOMMENDATION when contained by ENTITY of same type");
end
// Rule unit: X.7 // Rule unit: X.7
rule "X.7.0: Remove all images" rule "X.7.0: Remove all images"
salience 512 salience 512

View File

@ -243,7 +243,7 @@ public abstract class AbstractRedactionIntegrationTest {
public static void init() { public static void init() {
synchronized (PDFNet.class) { synchronized (PDFNet.class) {
PDFNet.initialize("demo:admin@knecon.com:7ed45ca80200000000c1e1765b94afccf5bbc0cb8582fd932c602e286a"); PDFNet.initialize("demo:1650351709282:7bd235e003000000004ec28a6743e1163a085e2115de2536ab6e2cfe5a");
} }
} }

View File

@ -169,7 +169,7 @@ import lombok.extern.slf4j.Slf4j;
public static void init() { public static void init() {
synchronized (PDFNet.class) { synchronized (PDFNet.class) {
PDFNet.initialize("demo:admin@knecon.com:7ed45ca80200000000c1e1765b94afccf5bbc0cb8582fd932c602e286a"); PDFNet.initialize("demo:1650351709282:7bd235e003000000004ec28a6743e1163a085e2115de2536ab6e2cfe5a");
} }
} }

View File

@ -261,6 +261,7 @@ public class DocumineFloraTest extends AbstractRedactionIntegrationTest {
} }
@Disabled
@Test @Test
public void testDoseMortalityExtraction() { public void testDoseMortalityExtraction() {

View File

@ -1654,46 +1654,35 @@ public class RedactionIntegrationTest extends RulesIntegrationTest {
.get(); .get();
request.setManualRedactions(ManualRedactions.builder() request.setManualRedactions(ManualRedactions.builder()
.entriesToAdd(Set.of(ManualRedactionEntry.builder()
.annotationId("newId")
.fileId(TEST_FILE_ID)
.user("user")
.requestDate(OffsetDateTime.now())
.value("David Ksenia")
.type("CBI_author")
.positions(List.of(Rectangle.builder().topLeftX(56.8f).topLeftY(295.2f).width(65.59f).height(12.64f).page(1).build()))
.build()))
.resizeRedactions(Set.of(ManualResizeRedaction.builder() .resizeRedactions(Set.of(ManualResizeRedaction.builder()
.updateDictionary(false) .updateDictionary(false)
.annotationId("newId") .annotationId(davidKsenia.getId())
.fileId(TEST_FILE_ID) .fileId(TEST_FILE_ID)
.user("user") .user("user")
.requestDate(OffsetDateTime.now()) .requestDate(OffsetDateTime.now())
.value("David") .value("David")
.positions(List.of(Rectangle.builder().topLeftX(56.8f).topLeftY(293.564f).width(29.2922f).height(15.408f).page(1).build())) .positions(List.of(Rectangle.builder()
.topLeftX(56.8f)
.topLeftY(293.564f)
.width(29.2922f)
.height(15.408f)
.page(1)
.build()))
.addToAllDossiers(false) .addToAllDossiers(false)
.build())) .build()))
.build()); .build());
analyzeService.reanalyze(request); analyzeService.reanalyze(request);
entityLog = redactionStorageService.getEntityLog(TEST_DOSSIER_ID, TEST_FILE_ID); entityLog = redactionStorageService.getEntityLog(TEST_DOSSIER_ID, TEST_FILE_ID);
var resizedEntity = entityLog.getEntityLogEntry() var resizedEntity = entityLog.getEntityLogEntry()
.stream()
.filter(e -> e.getId().equals("newId"))
.findFirst()
.get();
var removedEntity = entityLog.getEntityLogEntry()
.stream() .stream()
.filter(e -> e.getId().equals(davidKsenia.getId())) .filter(e -> e.getId().equals(davidKsenia.getId()))
.findFirst() .findFirst()
.get(); .get();
assertEquals(resizedEntity.getState(), EntryState.APPLIED);
assertEquals(EntryState.APPLIED, resizedEntity.getState()); assertEquals(resizedEntity.getValue(), "David");
assertEquals("David", resizedEntity.getValue()); assertEquals(1, resizedEntity.getManualChanges().size());
assertEquals(2, resizedEntity.getManualChanges().size()); assertEquals(resizedEntity.getManualChanges()
assertEquals(1, resizedEntity.getEngines().size()); .get(0).getManualRedactionType(), ManualRedactionType.RESIZE);
assertEquals(EntryState.REMOVED, removedEntity.getState());
} }
@ -2364,10 +2353,8 @@ public class RedactionIntegrationTest extends RulesIntegrationTest {
assertEquals(entityLog.getEntityLogEntry().size(), 3); assertEquals(entityLog.getEntityLogEntry().size(), 3);
} }
@Test @Test
public void testPurityRule() { public void testPurityRule() {
String EFSA_SANITISATION_RULES = loadFromClassPath("drools/efsa_sanitisation.drl"); String EFSA_SANITISATION_RULES = loadFromClassPath("drools/efsa_sanitisation.drl");
when(rulesClient.getRules(TEST_DOSSIER_TEMPLATE_ID, RuleFileType.ENTITY)).thenReturn(JSONPrimitive.of(EFSA_SANITISATION_RULES)); when(rulesClient.getRules(TEST_DOSSIER_TEMPLATE_ID, RuleFileType.ENTITY)).thenReturn(JSONPrimitive.of(EFSA_SANITISATION_RULES));
@ -2376,10 +2363,7 @@ public class RedactionIntegrationTest extends RulesIntegrationTest {
analyzeService.analyze(request); analyzeService.analyze(request);
var entityLog = redactionStorageService.getEntityLog(TEST_DOSSIER_ID, TEST_FILE_ID); var entityLog = redactionStorageService.getEntityLog(TEST_DOSSIER_ID, TEST_FILE_ID);
var entriesCount = entityLog.getEntityLogEntry() var entriesCount = entityLog.getEntityLogEntry().stream().filter(e -> e.getValue().toLowerCase(Locale.ENGLISH).startsWith("purity")).collect(Collectors.toList()).size();
.stream()
.filter(e -> e.getValue().toLowerCase(Locale.ENGLISH).startsWith("purity"))
.collect(Collectors.toList()).size();
assertEquals(7, entriesCount); assertEquals(7, entriesCount);
} }

View File

@ -158,7 +158,7 @@ public class PrecursorEntityTest extends BuildDocumentIntegrationTest {
Document document = buildGraph("files/syngenta/CustomerFiles/VV-919901.pdf"); Document document = buildGraph("files/syngenta/CustomerFiles/VV-919901.pdf");
EntityCreationService entityCreationService = new EntityCreationService(); EntityCreationService entityCreationService = new EntityCreationService();
List<TextEntity> tempEntities = entityCreationService.byString("To: Syngenta Ltd.", "temp", EntityType.TEMPORARY, document) List<TextEntity> tempEntities = entityCreationService.byString("To: Syngenta Ltd.", "temp", EntityType.ENTITY, document)
.toList(); .toList();
assertFalse(tempEntities.isEmpty()); assertFalse(tempEntities.isEmpty());
var tempEntity = tempEntities.get(0); var tempEntity = tempEntities.get(0);

View File

@ -11,6 +11,7 @@ Sude Halide Nurullah
Xinyi Y. Tao Xinyi Y. Tao
Dorn Dorn
Prasher Prasher
David
annotation annotation
J.B. RASCLE J.B. RASCLE
(果梗を除去したもの) (果梗を除去したもの)

View File

@ -1237,7 +1237,7 @@ rule "MAN.4.1: Apply legal basis change"
//------------------------------------ Entity merging rules ------------------------------------ //------------------------------------ Entity merging rules ------------------------------------
// Rule unit: X.0 // Rule unit: X.0
rule "X.0.0: Remove Entity contained by Entity of same type" rule "X.0.0: Remove Container Entity Contained by Container of Same Type"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -1262,7 +1262,7 @@ rule "X.0.0: Remove Entity contained by Entity of same type"
$contained.remove("X.0.0", "remove Entity contained by Entity of same type"); $contained.remove("X.0.0", "remove Entity contained by Entity of same type");
end end
rule "X.0.1: Remove Entity contained by Entity of same type with manual changes" rule "X.0.1: Remove Container and Contained Entities with Manual Changes"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -1282,7 +1282,7 @@ end
// Rule unit: X.2 // Rule unit: X.2
rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE" rule "X.2.0: Remove ENTITY and FALSE_POSITIVE Containing It"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -1298,7 +1298,7 @@ rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE"
$contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE"); $contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE");
end end
rule "X.2.1: Remove Entity of type HINT when contained by FALSE_POSITIVE" rule "X.2.1: Remove HINT Contained by FALSE_POSITIVE"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -1315,7 +1315,6 @@ rule "X.2.1: Remove Entity of type HINT when contained by FALSE_POSITIVE"
end end
// Rule unit: X.3
rule "X.3.0: Remove RECOMMENDATION Contained by FALSE_RECOMMENDATION" rule "X.3.0: Remove RECOMMENDATION Contained by FALSE_RECOMMENDATION"
salience 64 salience 64
when when
@ -1368,7 +1367,7 @@ rule "X.5.0: Remove Entity of type RECOMMENDATION when intersected by ENTITY"
$b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY"); $b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY");
end end
rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATION" rule "X.5.1: Remove Lower Priority RECOMMENDATION Contained by Higher Priority RECOMMENDATION"
salience 256 salience 256
when when
$containment: Containment( $containment: Containment(
@ -1385,23 +1384,6 @@ rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATI
end end
rule "X.5.2: Remove Entity of type RECOMMENDATION when contained by ENTITY of same type"
salience 256
when
$intersection: Containment(
$container: container,
$contained: contained,
($container.entityType == EntityType.ENTITY || $container.entityType == EntityType.HINT),
!$container.removed(),
$contained.entityType == EntityType.RECOMMENDATION,
$container.type() == $contained.type(),
!$contained.hasManualChanges()
)
then
$contained.remove("X.5.2", "remove Entity of type RECOMMENDATION when contained by ENTITY of same type");
end
// Rule unit: X.6 // Rule unit: X.6
rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT" rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT"
salience 32 salience 32
@ -1419,7 +1401,7 @@ rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT"
$contained.remove("X.6.0", "remove Entity of lower rank when contained by entity of type ENTITY or HINT"); $contained.remove("X.6.0", "remove Entity of lower rank when contained by entity of type ENTITY or HINT");
end end
rule "X.6.1: Remove Entity, when contained in another entity of type ENTITY or HINT with larger text range" rule "X.6.1: Remove Smaller Text Range Contained by ENTITY or HINT"
salience 32 salience 32
when when
$containment: Containment( $containment: Containment(

View File

@ -2001,7 +2001,7 @@ rule "MAN.4.1: Apply legal basis change"
//------------------------------------ Entity merging rules ------------------------------------ //------------------------------------ Entity merging rules ------------------------------------
// Rule unit: X.0 // Rule unit: X.0
rule "X.0.0: Remove Entity contained by Entity of same type" rule "X.0.0: Remove Container Entity Contained by Container of Same Type"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -2026,7 +2026,7 @@ rule "X.0.0: Remove Entity contained by Entity of same type"
$contained.remove("X.0.0", "remove Entity contained by Entity of same type"); $contained.remove("X.0.0", "remove Entity contained by Entity of same type");
end end
rule "X.0.1: Remove Entity contained by Entity of same type with manual changes" rule "X.0.1: Remove Container and Contained Entities with Manual Changes"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -2046,7 +2046,7 @@ end
// Rule unit: X.2 // Rule unit: X.2
rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE" rule "X.2.0: Remove ENTITY and FALSE_POSITIVE Containing It"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -2062,7 +2062,7 @@ rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE"
$contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE"); $contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE");
end end
rule "X.2.1: Remove Entity of type HINT when contained by FALSE_POSITIVE" rule "X.2.1: Remove HINT Contained by FALSE_POSITIVE"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -2079,7 +2079,6 @@ rule "X.2.1: Remove Entity of type HINT when contained by FALSE_POSITIVE"
end end
// Rule unit: X.3
rule "X.3.0: Remove RECOMMENDATION Contained by FALSE_RECOMMENDATION" rule "X.3.0: Remove RECOMMENDATION Contained by FALSE_RECOMMENDATION"
salience 64 salience 64
when when
@ -2132,7 +2131,7 @@ rule "X.5.0: Remove Entity of type RECOMMENDATION when intersected by ENTITY"
$b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY"); $b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY");
end end
rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATION" rule "X.5.1: Remove Lower Priority RECOMMENDATION Contained by Higher Priority RECOMMENDATION"
salience 256 salience 256
when when
$containment: Containment( $containment: Containment(
@ -2149,23 +2148,6 @@ rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATI
end end
rule "X.5.2: Remove Entity of type RECOMMENDATION when contained by ENTITY of same type"
salience 256
when
$intersection: Containment(
$container: container,
$contained: contained,
($container.entityType == EntityType.ENTITY || $container.entityType == EntityType.HINT),
!$container.removed(),
$contained.entityType == EntityType.RECOMMENDATION,
$container.type() == $contained.type(),
!$contained.hasManualChanges()
)
then
$contained.remove("X.5.2", "remove Entity of type RECOMMENDATION when contained by ENTITY of same type");
end
// Rule unit: X.6 // Rule unit: X.6
rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT" rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT"
salience 32 salience 32
@ -2183,7 +2165,7 @@ rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT"
$contained.remove("X.6.0", "remove Entity of lower rank when contained by entity of type ENTITY or HINT"); $contained.remove("X.6.0", "remove Entity of lower rank when contained by entity of type ENTITY or HINT");
end end
rule "X.6.1: Remove Entity, when contained in another entity of type ENTITY or HINT with larger text range" rule "X.6.1: Remove Smaller Text Range Contained by ENTITY or HINT"
salience 32 salience 32
when when
$containment: Containment( $containment: Containment(

View File

@ -1373,7 +1373,7 @@ rule "MAN.4.1: Apply legal basis change"
//------------------------------------ Entity merging rules ------------------------------------ //------------------------------------ Entity merging rules ------------------------------------
// Rule unit: X.0 // Rule unit: X.0
rule "X.0.0: Remove Entity contained by Entity of same type" rule "X.0.0: Remove Container Entity Contained by Container of Same Type"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -1398,7 +1398,7 @@ rule "X.0.0: Remove Entity contained by Entity of same type"
$contained.remove("X.0.0", "remove Entity contained by Entity of same type"); $contained.remove("X.0.0", "remove Entity contained by Entity of same type");
end end
rule "X.0.1: Remove Entity contained by Entity of same type with manual changes" rule "X.0.1: Remove Container and Contained Entities with Manual Changes"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -1418,7 +1418,7 @@ end
// Rule unit: X.2 // Rule unit: X.2
rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE" rule "X.2.0: Remove ENTITY and FALSE_POSITIVE Containing It"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -1434,7 +1434,7 @@ rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE"
$contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE"); $contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE");
end end
rule "X.2.1: Remove Entity of type HINT when contained by FALSE_POSITIVE" rule "X.2.1: Remove HINT Contained by FALSE_POSITIVE"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -1451,7 +1451,6 @@ rule "X.2.1: Remove Entity of type HINT when contained by FALSE_POSITIVE"
end end
// Rule unit: X.3
rule "X.3.0: Remove RECOMMENDATION Contained by FALSE_RECOMMENDATION" rule "X.3.0: Remove RECOMMENDATION Contained by FALSE_RECOMMENDATION"
salience 64 salience 64
when when
@ -1504,7 +1503,7 @@ rule "X.5.0: Remove Entity of type RECOMMENDATION when intersected by ENTITY"
$b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY"); $b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY");
end end
rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATION" rule "X.5.1: Remove Lower Priority RECOMMENDATION Contained by Higher Priority RECOMMENDATION"
salience 256 salience 256
when when
$containment: Containment( $containment: Containment(
@ -1521,23 +1520,6 @@ rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATI
end end
rule "X.5.2: Remove Entity of type RECOMMENDATION when contained by ENTITY of same type"
salience 256
when
$intersection: Containment(
$container: container,
$contained: contained,
($container.entityType == EntityType.ENTITY || $container.entityType == EntityType.HINT),
!$container.removed(),
$contained.entityType == EntityType.RECOMMENDATION,
$container.type() == $contained.type(),
!$contained.hasManualChanges()
)
then
$contained.remove("X.5.2", "remove Entity of type RECOMMENDATION when contained by ENTITY of same type");
end
// Rule unit: X.7 // Rule unit: X.7
rule "X.7.0: Remove all images" rule "X.7.0: Remove all images"
salience 512 salience 512

View File

@ -964,7 +964,7 @@ rule "MAN.4.1: Apply legal basis change"
//------------------------------------ Entity merging rules ------------------------------------ //------------------------------------ Entity merging rules ------------------------------------
// Rule unit: X.0 // Rule unit: X.0
rule "X.0.0: Remove Entity contained by Entity of same type" rule "X.0.0: Remove Container Entity Contained by Container of Same Type"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -989,7 +989,7 @@ rule "X.0.0: Remove Entity contained by Entity of same type"
$contained.remove("X.0.0", "remove Entity contained by Entity of same type"); $contained.remove("X.0.0", "remove Entity contained by Entity of same type");
end end
rule "X.0.1: Remove Entity contained by Entity of same type with manual changes" rule "X.0.1: Remove Container and Contained Entities with Manual Changes"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -1009,7 +1009,7 @@ end
// Rule unit: X.2 // Rule unit: X.2
rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE" rule "X.2.0: Remove ENTITY and FALSE_POSITIVE Containing It"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -1025,7 +1025,7 @@ rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE"
$contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE"); $contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE");
end end
rule "X.2.1: Remove Entity of type HINT when contained by FALSE_POSITIVE" rule "X.2.1: Remove HINT Contained by FALSE_POSITIVE"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -1042,7 +1042,6 @@ rule "X.2.1: Remove Entity of type HINT when contained by FALSE_POSITIVE"
end end
// Rule unit: X.3
rule "X.3.0: Remove RECOMMENDATION Contained by FALSE_RECOMMENDATION" rule "X.3.0: Remove RECOMMENDATION Contained by FALSE_RECOMMENDATION"
salience 64 salience 64
when when
@ -1095,7 +1094,7 @@ rule "X.5.0: Remove Entity of type RECOMMENDATION when intersected by ENTITY"
$b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY"); $b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY");
end end
rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATION" rule "X.5.1: Remove Lower Priority RECOMMENDATION Contained by Higher Priority RECOMMENDATION"
salience 256 salience 256
when when
$containment: Containment( $containment: Containment(
@ -1112,23 +1111,6 @@ rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATI
end end
rule "X.5.2: Remove Entity of type RECOMMENDATION when contained by ENTITY of same type"
salience 256
when
$intersection: Containment(
$container: container,
$contained: contained,
($container.entityType == EntityType.ENTITY || $container.entityType == EntityType.HINT),
!$container.removed(),
$contained.entityType == EntityType.RECOMMENDATION,
$container.type() == $contained.type(),
!$contained.hasManualChanges()
)
then
$contained.remove("X.5.2", "remove Entity of type RECOMMENDATION when contained by ENTITY of same type");
end
// Rule unit: X.6 // Rule unit: X.6
rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT" rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT"
salience 32 salience 32
@ -1146,7 +1128,7 @@ rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT"
$contained.remove("X.6.0", "remove Entity of lower rank when contained by entity of type ENTITY or HINT"); $contained.remove("X.6.0", "remove Entity of lower rank when contained by entity of type ENTITY or HINT");
end end
rule "X.6.1: Remove Entity, when contained in another entity of type ENTITY or HINT with larger text range" rule "X.6.1: Remove Smaller Text Range Contained by ENTITY or HINT"
salience 32 salience 32
when when
$containment: Containment( $containment: Containment(

View File

@ -285,7 +285,7 @@ rule "MAN.4.1: Apply legal basis change"
//------------------------------------ Entity merging rules ------------------------------------ //------------------------------------ Entity merging rules ------------------------------------
// Rule unit: X.0 // Rule unit: X.0
rule "X.0.0: Remove Entity contained by Entity of same type" rule "X.0.0: Remove Container Entity Contained by Container of Same Type"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -310,7 +310,7 @@ rule "X.0.0: Remove Entity contained by Entity of same type"
$contained.remove("X.0.0", "remove Entity contained by Entity of same type"); $contained.remove("X.0.0", "remove Entity contained by Entity of same type");
end end
rule "X.0.1: Remove Entity contained by Entity of same type with manual changes" rule "X.0.1: Remove Container and Contained Entities with Manual Changes"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -330,7 +330,7 @@ end
// Rule unit: X.2 // Rule unit: X.2
rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE" rule "X.2.0: Remove ENTITY and FALSE_POSITIVE Containing It"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -346,7 +346,7 @@ rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE"
$contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE"); $contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE");
end end
rule "X.2.1: Remove Entity of type HINT when contained by FALSE_POSITIVE" rule "X.2.1: Remove HINT Contained by FALSE_POSITIVE"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -363,7 +363,6 @@ rule "X.2.1: Remove Entity of type HINT when contained by FALSE_POSITIVE"
end end
// Rule unit: X.3
rule "X.3.0: Remove RECOMMENDATION Contained by FALSE_RECOMMENDATION" rule "X.3.0: Remove RECOMMENDATION Contained by FALSE_RECOMMENDATION"
salience 64 salience 64
when when
@ -416,7 +415,7 @@ rule "X.5.0: Remove Entity of type RECOMMENDATION when intersected by ENTITY"
$b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY"); $b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY");
end end
rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATION" rule "X.5.1: Remove Lower Priority RECOMMENDATION Contained by Higher Priority RECOMMENDATION"
salience 256 salience 256
when when
$containment: Containment( $containment: Containment(
@ -433,23 +432,6 @@ rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATI
end end
rule "X.5.2: Remove Entity of type RECOMMENDATION when contained by ENTITY of same type"
salience 256
when
$intersection: Containment(
$container: container,
$contained: contained,
($container.entityType == EntityType.ENTITY || $container.entityType == EntityType.HINT),
!$container.removed(),
$contained.entityType == EntityType.RECOMMENDATION,
$container.type() == $contained.type(),
!$contained.hasManualChanges()
)
then
$contained.remove("X.5.2", "remove Entity of type RECOMMENDATION when contained by ENTITY of same type");
end
// Rule unit: X.6 // Rule unit: X.6
rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT" rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT"
salience 32 salience 32
@ -467,7 +449,7 @@ rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT"
$contained.remove("X.6.0", "remove Entity of lower rank when contained by entity of type ENTITY or HINT"); $contained.remove("X.6.0", "remove Entity of lower rank when contained by entity of type ENTITY or HINT");
end end
rule "X.6.1: Remove Entity, when contained in another entity of type ENTITY or HINT with larger text range" rule "X.6.1: Remove Smaller Text Range Contained by ENTITY or HINT"
salience 32 salience 32
when when
$containment: Containment( $containment: Containment(

View File

@ -1258,9 +1258,8 @@ rule "MAN.4.1: Apply legal basis change"
//------------------------------------ Entity merging rules ------------------------------------ //------------------------------------ Entity merging rules ------------------------------------
// Rule unit: X.0 // Rule unit: X.0
rule "X.0.0: Remove Entity contained by Entity of same type" rule "X.0.0: Remove Container Entity Contained by Container of Same Type"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -1285,7 +1284,7 @@ rule "X.0.0: Remove Entity contained by Entity of same type"
$contained.remove("X.0.0", "remove Entity contained by Entity of same type"); $contained.remove("X.0.0", "remove Entity contained by Entity of same type");
end end
rule "X.0.1: Remove Entity contained by Entity of same type with manual changes" rule "X.0.1: Remove Container and Contained Entities with Manual Changes"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -1303,9 +1302,8 @@ rule "X.0.1: Remove Entity contained by Entity of same type with manual changes"
$contained.remove("X.0.1", "remove Entity contained by Entity of same type with manual changes"); $contained.remove("X.0.1", "remove Entity contained by Entity of same type with manual changes");
end end
// Rule unit: X.2 // Rule unit: X.2
rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE" rule "X.2.0: Remove ENTITY and FALSE_POSITIVE Containing It"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -1321,7 +1319,7 @@ rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE"
$contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE"); $contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE");
end end
rule "X.2.1: Remove Entity of type HINT when contained by FALSE_POSITIVE" rule "X.2.1: Remove HINT Contained by FALSE_POSITIVE"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -1337,7 +1335,6 @@ rule "X.2.1: Remove Entity of type HINT when contained by FALSE_POSITIVE"
$contained.remove("X.2.1", "remove Entity of type HINT when contained by FALSE_POSITIVE"); $contained.remove("X.2.1", "remove Entity of type HINT when contained by FALSE_POSITIVE");
end end
// Rule unit: X.3 // Rule unit: X.3
rule "X.3.0: Remove RECOMMENDATION Contained by FALSE_RECOMMENDATION" rule "X.3.0: Remove RECOMMENDATION Contained by FALSE_RECOMMENDATION"
salience 64 salience 64
@ -1355,7 +1352,6 @@ rule "X.3.0: Remove RECOMMENDATION Contained by FALSE_RECOMMENDATION"
$contained.remove("X.3.0", "remove Entity of type RECOMMENDATION when contained by FALSE_RECOMMENDATION"); $contained.remove("X.3.0", "remove Entity of type RECOMMENDATION when contained by FALSE_RECOMMENDATION");
end end
// Rule unit: X.4 // Rule unit: X.4
rule "X.4.0: Remove Entity of type RECOMMENDATION when text range equals ENTITY with same type" rule "X.4.0: Remove Entity of type RECOMMENDATION when text range equals ENTITY with same type"
salience 256 salience 256
@ -1374,7 +1370,6 @@ rule "X.4.0: Remove Entity of type RECOMMENDATION when text range equals ENTITY
$b.remove("X.4.0", "remove Entity of type RECOMMENDATION when text range equals ENTITY with same type"); $b.remove("X.4.0", "remove Entity of type RECOMMENDATION when text range equals ENTITY with same type");
end end
// Rule unit: X.5 // Rule unit: X.5
rule "X.5.0: Remove Entity of type RECOMMENDATION when intersected by ENTITY" rule "X.5.0: Remove Entity of type RECOMMENDATION when intersected by ENTITY"
salience 256 salience 256
@ -1391,7 +1386,7 @@ rule "X.5.0: Remove Entity of type RECOMMENDATION when intersected by ENTITY"
$b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY"); $b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY");
end end
rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATION" rule "X.5.1: Remove Lower Priority RECOMMENDATION Contained by Higher Priority RECOMMENDATION"
salience 256 salience 256
when when
$containment: Containment( $containment: Containment(
@ -1407,24 +1402,6 @@ rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATI
$contained.remove("X.5.1", "remove Entity of type RECOMMENDATION when contained by RECOMMENDATION"); $contained.remove("X.5.1", "remove Entity of type RECOMMENDATION when contained by RECOMMENDATION");
end end
rule "X.5.2: Remove Entity of type RECOMMENDATION when contained by ENTITY of same type"
salience 256
when
$intersection: Containment(
$container: container,
$contained: contained,
($container.entityType == EntityType.ENTITY || $container.entityType == EntityType.HINT),
!$container.removed(),
$contained.entityType == EntityType.RECOMMENDATION,
$container.type() == $contained.type(),
!$contained.hasManualChanges()
)
then
$contained.remove("X.5.2", "remove Entity of type RECOMMENDATION when contained by ENTITY of same type");
end
// Rule unit: X.6 // Rule unit: X.6
rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT" rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT"
salience 32 salience 32
@ -1442,7 +1419,7 @@ rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT"
$contained.remove("X.6.0", "remove Entity of lower rank when contained by entity of type ENTITY or HINT"); $contained.remove("X.6.0", "remove Entity of lower rank when contained by entity of type ENTITY or HINT");
end end
rule "X.6.1: Remove Entity, when contained in another entity of type ENTITY or HINT with larger text range" rule "X.6.1: Remove Smaller Text Range Contained by ENTITY or HINT"
salience 32 salience 32
when when
$containment: Containment( $containment: Containment(
@ -1458,7 +1435,6 @@ rule "X.6.1: Remove Entity, when contained in another entity of type ENTITY or H
$contained.remove("X.6.1", "remove Entity when contained in another entity of type ENTITY or HINT with larger text range"); $contained.remove("X.6.1", "remove Entity when contained in another entity of type ENTITY or HINT with larger text range");
end end
// Rule unit: X.8 // Rule unit: X.8
rule "X.8.0: Remove Entity when text range and type equals to imported Entity" rule "X.8.0: Remove Entity when text range and type equals to imported Entity"
salience 257 salience 257
@ -1492,7 +1468,6 @@ rule "X.8.1: Remove Entity when intersected by imported Entity"
$b.remove("X.8.1", "remove Entity when intersected by imported Entity"); $b.remove("X.8.1", "remove Entity when intersected by imported Entity");
end end
// Rule unit: X.9 // Rule unit: X.9
rule "X.9.0: Merge mostly contained signatures" rule "X.9.0: Merge mostly contained signatures"
when when
@ -1513,7 +1488,6 @@ rule "X.10.0: remove false positives of ai"
$aiSignature.remove("X.10.0", "Removed because false positive"); $aiSignature.remove("X.10.0", "Removed because false positive");
end end
// Rule unit: X.11 // Rule unit: X.11
rule "X.11.1: Remove non-manual entity which intersects with a manual entity" rule "X.11.1: Remove non-manual entity which intersects with a manual entity"
salience 64 salience 64
@ -1548,6 +1522,7 @@ rule "X.11.2: Remove non-manual entity which is equal to manual entity"
end end
//------------------------------------ Dictionary merging rules ------------------------------------ //------------------------------------ Dictionary merging rules ------------------------------------
// Rule unit: DICT.0 // Rule unit: DICT.0

View File

@ -345,7 +345,7 @@ rule "MAN.4.1: Apply legal basis change"
//------------------------------------ Entity merging rules ------------------------------------ //------------------------------------ Entity merging rules ------------------------------------
// Rule unit: X.0 // Rule unit: X.0
rule "X.0.0: Remove Entity contained by Entity of same type" rule "X.0.0: Remove Container Entity Contained by Container of Same Type"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -370,7 +370,7 @@ rule "X.0.0: Remove Entity contained by Entity of same type"
$contained.remove("X.0.0", "remove Entity contained by Entity of same type"); $contained.remove("X.0.0", "remove Entity contained by Entity of same type");
end end
rule "X.0.1: Remove Entity contained by Entity of same type with manual changes" rule "X.0.1: Remove Container and Contained Entities with Manual Changes"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -390,7 +390,7 @@ end
// Rule unit: X.2 // Rule unit: X.2
rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE" rule "X.2.0: Remove ENTITY and FALSE_POSITIVE Containing It"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -406,7 +406,7 @@ rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE"
$contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE"); $contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE");
end end
rule "X.2.1: Remove Entity of type HINT when contained by FALSE_POSITIVE" rule "X.2.1: Remove HINT Contained by FALSE_POSITIVE"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -423,7 +423,6 @@ rule "X.2.1: Remove Entity of type HINT when contained by FALSE_POSITIVE"
end end
// Rule unit: X.3
rule "X.3.0: Remove RECOMMENDATION Contained by FALSE_RECOMMENDATION" rule "X.3.0: Remove RECOMMENDATION Contained by FALSE_RECOMMENDATION"
salience 64 salience 64
when when
@ -476,7 +475,7 @@ rule "X.5.0: Remove Entity of type RECOMMENDATION when intersected by ENTITY"
$b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY"); $b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY");
end end
rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATION" rule "X.5.1: Remove Lower Priority RECOMMENDATION Contained by Higher Priority RECOMMENDATION"
salience 256 salience 256
when when
$containment: Containment( $containment: Containment(
@ -493,23 +492,6 @@ rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATI
end end
rule "X.5.2: Remove Entity of type RECOMMENDATION when contained by ENTITY of same type"
salience 256
when
$intersection: Containment(
$container: container,
$contained: contained,
($container.entityType == EntityType.ENTITY || $container.entityType == EntityType.HINT),
!$container.removed(),
$contained.entityType == EntityType.RECOMMENDATION,
$container.type() == $contained.type(),
!$contained.hasManualChanges()
)
then
$contained.remove("X.5.2", "remove Entity of type RECOMMENDATION when contained by ENTITY of same type");
end
// Rule unit: X.6 // Rule unit: X.6
rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT" rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT"
salience 32 salience 32
@ -527,7 +509,7 @@ rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT"
$contained.remove("X.6.0", "remove Entity of lower rank when contained by entity of type ENTITY or HINT"); $contained.remove("X.6.0", "remove Entity of lower rank when contained by entity of type ENTITY or HINT");
end end
rule "X.6.1: Remove Entity, when contained in another entity of type ENTITY or HINT with larger text range" rule "X.6.1: Remove Smaller Text Range Contained by ENTITY or HINT"
salience 32 salience 32
when when
$containment: Containment( $containment: Containment(

View File

@ -435,7 +435,7 @@ rule "MAN.4.1: Apply legal basis change"
//------------------------------------ Entity merging rules ------------------------------------ //------------------------------------ Entity merging rules ------------------------------------
// Rule unit: X.0 // Rule unit: X.0
rule "X.0.0: Remove Entity contained by Entity of same type" rule "X.0.0: Remove Container Entity Contained by Container of Same Type"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -460,7 +460,7 @@ rule "X.0.0: Remove Entity contained by Entity of same type"
$contained.remove("X.0.0", "remove Entity contained by Entity of same type"); $contained.remove("X.0.0", "remove Entity contained by Entity of same type");
end end
rule "X.0.1: Remove Entity contained by Entity of same type with manual changes" rule "X.0.1: Remove Container and Contained Entities with Manual Changes"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -480,7 +480,7 @@ end
// Rule unit: X.2 // Rule unit: X.2
rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE" rule "X.2.0: Remove ENTITY and FALSE_POSITIVE Containing It"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -496,7 +496,7 @@ rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE"
$contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE"); $contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE");
end end
rule "X.2.1: Remove Entity of type HINT when contained by FALSE_POSITIVE" rule "X.2.1: Remove HINT Contained by FALSE_POSITIVE"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -513,7 +513,6 @@ rule "X.2.1: Remove Entity of type HINT when contained by FALSE_POSITIVE"
end end
// Rule unit: X.3
rule "X.3.0: Remove RECOMMENDATION Contained by FALSE_RECOMMENDATION" rule "X.3.0: Remove RECOMMENDATION Contained by FALSE_RECOMMENDATION"
salience 64 salience 64
when when
@ -566,7 +565,7 @@ rule "X.5.0: Remove Entity of type RECOMMENDATION when intersected by ENTITY"
$b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY"); $b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY");
end end
rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATION" rule "X.5.1: Remove Lower Priority RECOMMENDATION Contained by Higher Priority RECOMMENDATION"
salience 256 salience 256
when when
$containment: Containment( $containment: Containment(
@ -583,23 +582,6 @@ rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATI
end end
rule "X.5.2: Remove Entity of type RECOMMENDATION when contained by ENTITY of same type"
salience 256
when
$intersection: Containment(
$container: container,
$contained: contained,
($container.entityType == EntityType.ENTITY || $container.entityType == EntityType.HINT),
!$container.removed(),
$contained.entityType == EntityType.RECOMMENDATION,
$container.type() == $contained.type(),
!$contained.hasManualChanges()
)
then
$contained.remove("X.5.2", "remove Entity of type RECOMMENDATION when contained by ENTITY of same type");
end
// Rule unit: X.6 // Rule unit: X.6
rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT" rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT"
salience 32 salience 32
@ -617,7 +599,7 @@ rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT"
$contained.remove("X.6.0", "remove Entity of lower rank when contained by entity of type ENTITY or HINT"); $contained.remove("X.6.0", "remove Entity of lower rank when contained by entity of type ENTITY or HINT");
end end
rule "X.6.1: Remove Entity, when contained in another entity of type ENTITY or HINT with larger text range" rule "X.6.1: Remove Smaller Text Range Contained by ENTITY or HINT"
salience 32 salience 32
when when
$containment: Containment( $containment: Containment(

View File

@ -335,7 +335,7 @@ rule "MAN.4.1: Apply legal basis change"
//------------------------------------ Entity merging rules ------------------------------------ //------------------------------------ Entity merging rules ------------------------------------
// Rule unit: X.0 // Rule unit: X.0
rule "X.0.0: Remove Entity contained by Entity of same type" rule "X.0.0: Remove Container Entity Contained by Container of Same Type"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -360,7 +360,7 @@ rule "X.0.0: Remove Entity contained by Entity of same type"
$contained.remove("X.0.0", "remove Entity contained by Entity of same type"); $contained.remove("X.0.0", "remove Entity contained by Entity of same type");
end end
rule "X.0.1: Remove Entity contained by Entity of same type with manual changes" rule "X.0.1: Remove Container and Contained Entities with Manual Changes"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -380,7 +380,7 @@ end
// Rule unit: X.2 // Rule unit: X.2
rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE" rule "X.2.0: Remove ENTITY and FALSE_POSITIVE Containing It"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -396,7 +396,39 @@ rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE"
$contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE"); $contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE");
end end
rule "X.2.1: Remove Entity of type HINT when contained by FALSE_POSITIVE" rule "X.2.0: Remove ENTITY and FALSE_POSITIVE Containing It"
salience 64
when
$containment: Containment(
$container: container,
$contained: contained,
$container.entityType == EntityType.FALSE_POSITIVE,
$container.active(),
$contained.entityType == EntityType.ENTITY,
$contained.type() == $container.type(),
!$contained.hasManualChanges()
)
then
$contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE");
end
rule "X.2.1: Remove HINT Contained by FALSE_POSITIVE"
salience 64
when
$containment: Containment(
$container: container,
$contained: contained,
$container.entityType == EntityType.FALSE_POSITIVE,
$container.active(),
$contained.entityType == EntityType.HINT,
$contained.type() == $container.type(),
!$contained.hasManualChanges()
)
then
$contained.remove("X.2.1", "remove Entity of type HINT when contained by FALSE_POSITIVE");
end
rule "X.2.1: Remove HINT Contained by FALSE_POSITIVE"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -413,7 +445,6 @@ rule "X.2.1: Remove Entity of type HINT when contained by FALSE_POSITIVE"
end end
// Rule unit: X.3
rule "X.3.0: Remove RECOMMENDATION Contained by FALSE_RECOMMENDATION" rule "X.3.0: Remove RECOMMENDATION Contained by FALSE_RECOMMENDATION"
salience 64 salience 64
when when
@ -466,7 +497,7 @@ rule "X.5.0: Remove Entity of type RECOMMENDATION when intersected by ENTITY"
$b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY"); $b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY");
end end
rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATION" rule "X.5.1: Remove Lower Priority RECOMMENDATION Contained by Higher Priority RECOMMENDATION"
salience 256 salience 256
when when
$containment: Containment( $containment: Containment(
@ -483,23 +514,6 @@ rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATI
end end
rule "X.5.2: Remove Entity of type RECOMMENDATION when contained by ENTITY of same type"
salience 256
when
$intersection: Containment(
$container: container,
$contained: contained,
($container.entityType == EntityType.ENTITY || $container.entityType == EntityType.HINT),
!$container.removed(),
$contained.entityType == EntityType.RECOMMENDATION,
$container.type() == $contained.type(),
!$contained.hasManualChanges()
)
then
$contained.remove("X.5.2", "remove Entity of type RECOMMENDATION when contained by ENTITY of same type");
end
// Rule unit: X.6 // Rule unit: X.6
rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT" rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT"
salience 32 salience 32
@ -517,7 +531,7 @@ rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT"
$contained.remove("X.6.0", "remove Entity of lower rank when contained by entity of type ENTITY or HINT"); $contained.remove("X.6.0", "remove Entity of lower rank when contained by entity of type ENTITY or HINT");
end end
rule "X.6.1: Remove Entity, when contained in another entity of type ENTITY or HINT with larger text range" rule "X.6.1: Remove Smaller Text Range Contained by ENTITY or HINT"
salience 32 salience 32
when when
$containment: Containment( $containment: Containment(

View File

@ -848,7 +848,7 @@ rule "MAN.4.1: Apply legal basis change"
//------------------------------------ Entity merging rules ------------------------------------ //------------------------------------ Entity merging rules ------------------------------------
// Rule unit: X.0 // Rule unit: X.0
rule "X.0.0: Remove Entity contained by Entity of same type" rule "X.0.0: Remove Container Entity Contained by Container of Same Type"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -873,7 +873,7 @@ rule "X.0.0: Remove Entity contained by Entity of same type"
$contained.remove("X.0.0", "remove Entity contained by Entity of same type"); $contained.remove("X.0.0", "remove Entity contained by Entity of same type");
end end
rule "X.0.1: Remove Entity contained by Entity of same type with manual changes" rule "X.0.1: Remove Container and Contained Entities with Manual Changes"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -893,7 +893,7 @@ end
// Rule unit: X.2 // Rule unit: X.2
rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE" rule "X.2.0: Remove ENTITY and FALSE_POSITIVE Containing It"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -909,7 +909,7 @@ rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE"
$contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE"); $contained.remove("X.2.0", "remove Entity of type ENTITY when contained by FALSE_POSITIVE");
end end
rule "X.2.1: Remove Entity of type HINT when contained by FALSE_POSITIVE" rule "X.2.1: Remove HINT Contained by FALSE_POSITIVE"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -978,7 +978,7 @@ rule "X.5.0: Remove Entity of type RECOMMENDATION when intersected by ENTITY"
$b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY"); $b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY");
end end
rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATION" rule "X.5.1: Remove Lower Priority RECOMMENDATION Contained by Higher Priority RECOMMENDATION"
salience 256 salience 256
when when
$containment: Containment( $containment: Containment(
@ -995,23 +995,6 @@ rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATI
end end
rule "X.5.2: Remove Entity of type RECOMMENDATION when contained by ENTITY of same type"
salience 256
when
$intersection: Containment(
$container: container,
$contained: contained,
($container.entityType == EntityType.ENTITY || $container.entityType == EntityType.HINT),
!$container.removed(),
$contained.entityType == EntityType.RECOMMENDATION,
$container.type() == $contained.type(),
!$contained.hasManualChanges()
)
then
$contained.remove("X.5.2", "remove Entity of type RECOMMENDATION when contained by ENTITY of same type");
end
// Rule unit: X.6 // Rule unit: X.6
rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT" rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT"
salience 32 salience 32
@ -1029,7 +1012,7 @@ rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT"
$contained.remove("X.6.0", "remove Entity of lower rank when contained by entity of type ENTITY or HINT"); $contained.remove("X.6.0", "remove Entity of lower rank when contained by entity of type ENTITY or HINT");
end end
rule "X.6.1: Remove Entity, when contained in another entity of type ENTITY or HINT with larger text range" rule "X.6.1: Remove Smaller Text Range Contained by ENTITY or HINT"
salience 32 salience 32
when when
$containment: Containment( $containment: Containment(

View File

@ -2020,7 +2020,7 @@ rule "MAN.4.1: Apply legal basis change"
//------------------------------------ Entity merging rules ------------------------------------ //------------------------------------ Entity merging rules ------------------------------------
// Rule unit: X.0 // Rule unit: X.0
rule "X.0.0: Remove Entity contained by Entity of same type" rule "X.0.0: Remove Container Entity Contained by Container of Same Type"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -2046,7 +2046,7 @@ rule "X.0.0: Remove Entity contained by Entity of same type"
end end
rule "X.0.1: Remove Entity contained by Entity of same type with manual changes" rule "X.0.1: Remove Container and Contained Entities with Manual Changes"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -2084,7 +2084,7 @@ rule "X.0.4: Remove Entity contained by Entity of same type"
end end
// Rule unit: X.2 // Rule unit: X.2
rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE" rule "X.2.0: Remove ENTITY and FALSE_POSITIVE Containing It"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -2101,7 +2101,7 @@ rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE"
end end
rule "X.2.1: Remove Entity of type HINT when contained by FALSE_POSITIVE" rule "X.2.1: Remove HINT Contained by FALSE_POSITIVE"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -2170,7 +2170,7 @@ rule "X.5.0: Remove Entity of type RECOMMENDATION when intersected by ENTITY"
$b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY"); $b.remove("X.5.0", "remove Entity of type RECOMMENDATION when intersected by ENTITY");
end end
rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATION" rule "X.5.1: Remove Lower Priority RECOMMENDATION Contained by Higher Priority RECOMMENDATION"
salience 256 salience 256
when when
$containment: Containment( $containment: Containment(
@ -2187,23 +2187,6 @@ rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATI
end end
rule "X.5.2: Remove Entity of type RECOMMENDATION when contained by ENTITY of same type"
salience 256
when
$intersection: Containment(
$container: container,
$contained: contained,
($container.entityType == EntityType.ENTITY || $container.entityType == EntityType.HINT),
!$container.removed(),
$contained.entityType == EntityType.RECOMMENDATION,
$container.type() == $contained.type(),
!$contained.hasManualChanges()
)
then
$contained.remove("X.5.2", "remove Entity of type RECOMMENDATION when contained by ENTITY of same type");
end
// Rule unit: X.6 // Rule unit: X.6
rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT" rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT"
salience 32 salience 32
@ -2221,7 +2204,7 @@ rule "X.6.0: Remove Lower Rank Entity Contained by ENTITY or HINT"
$contained.remove("X.6.0", "remove Entity of lower rank when contained by entity of type ENTITY or HINT"); $contained.remove("X.6.0", "remove Entity of lower rank when contained by entity of type ENTITY or HINT");
end end
rule "X.6.1: Remove Entity, when contained in another entity of type ENTITY or HINT with larger text range" rule "X.6.1: Remove Smaller Text Range Contained by ENTITY or HINT"
salience 32 salience 32
when when
$containment: Containment( $containment: Containment(

View File

@ -1439,7 +1439,7 @@ rule "MAN.4.1: Apply legal basis change"
//------------------------------------ Entity merging rules ------------------------------------ //------------------------------------ Entity merging rules ------------------------------------
// Rule unit: X.0 // Rule unit: X.0
rule "X.0.0: Remove Entity contained by Entity of same type" rule "X.0.0: Remove Container Entity Contained by Container of Same Type"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -1464,7 +1464,7 @@ rule "X.0.0: Remove Entity contained by Entity of same type"
$contained.remove("X.0.0", "remove Entity contained by Entity of same type"); $contained.remove("X.0.0", "remove Entity contained by Entity of same type");
end end
rule "X.0.1: Remove Entity contained by Entity of same type with manual changes" rule "X.0.1: Remove Container and Contained Entities with Manual Changes"
salience 65 salience 65
when when
$containment: Containment( $containment: Containment(
@ -1484,7 +1484,7 @@ end
// Rule unit: X.2 // Rule unit: X.2
rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE" rule "X.2.0: Remove ENTITY and FALSE_POSITIVE Containing It"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -1501,7 +1501,7 @@ rule "X.2.0: Remove Entity of type ENTITY when contained by FALSE_POSITIVE"
end end
rule "X.2.1: Remove Entity of type HINT when contained by FALSE_POSITIVE" rule "X.2.1: Remove HINT Contained by FALSE_POSITIVE"
salience 64 salience 64
when when
$containment: Containment( $containment: Containment(
@ -1572,7 +1572,7 @@ rule "X.5.0: Remove Entity of type RECOMMENDATION when intersected by ENTITY"
// Rule unit: X.5 // Rule unit: X.5
rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATION" rule "X.5.1: Remove Lower Priority RECOMMENDATION Contained by Higher Priority RECOMMENDATION"
salience 256 salience 256
when when
$containment: Containment( $containment: Containment(
@ -1589,23 +1589,6 @@ rule "X.5.1: Remove Entity of type RECOMMENDATION when contained by RECOMMENDATI
end end
rule "X.5.2: Remove Entity of type RECOMMENDATION when contained by ENTITY of same type"
salience 256
when
$intersection: Containment(
$container: container,
$contained: contained,
($container.entityType == EntityType.ENTITY || $container.entityType == EntityType.HINT),
!$container.removed(),
$contained.entityType == EntityType.RECOMMENDATION,
$container.type() == $contained.type(),
!$contained.hasManualChanges()
)
then
$contained.remove("X.5.2", "remove Entity of type RECOMMENDATION when contained by ENTITY of same type");
end
// Rule unit: X.7 // Rule unit: X.7
rule "X.7.0: Remove all images" rule "X.7.0: Remove all images"
salience 512 salience 512