Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Semantic filtering and tagging API #137

Closed
wants to merge 15 commits into from
Closed

Conversation

Eddykasp
Copy link
Contributor

@Eddykasp Eddykasp commented Jul 25, 2022

kieler/klighd-vscode#109

Wiki Page Draft

Semantic Filtering Tags

SemanticFilterTags can be added to a graph element with the property de.cau.cs.kieler.klighd.semanticFilter.tags. They contain a string that serves to convey semantic information. A tag also acts as an atomic SemanticFilterRule that evaluates to true for an element if that element contains a tag with the same string.

Semantic Filtering Rules

A graph element can contain a list of SemanticFilterRules. Depending on the intended use case it may make sense to attach different rules to different graph elements, but in the use cases we consider here, rules would apply to the entire graph. Therefore, rules are only attached to the root node. It is up to the client feature (e.g. proxy-view) to look for and apply rules on a graph.

Constructing Rules

A SemanticFilterTag, TrueConnective and FalseConnective are atomic rules. Rules can be constructed using connectives and other rules. The following logical connectives are defined:

  • IdentityConnective
  • NegationConnective
  • AndConnective
  • OrConnective
  • IfThenConnective
  • IfThenElseConnective

Numeric Tags and Rules

A SemanticFilterTag can also have a number in addition to a string and there are special numerical connectives that take a SemanticFilterTag as an operand and evaluate to true or false according to the number saved in that tag. The following numeric connectives are defined:

  • NumericEqualConnective
  • NumericNotEqualConnective
  • GreaterThanConnective
  • GreaterEqualsConnective
  • LessThanConnective
  • LessEqualsConnective

Numeric Connectives with Numeric Results

The following rules take numeric inputs and output a numeric value themselves. They can be used to construct more complex expressions such as "states" where the sum of "declarations" and "childCount" is larger than some value.

  • NumericPlusConnective
  • NumericMinusConnective
  • NumericTimesConnective
  • NumericDividesConnective

Code Examples

Adding tags and rules on the server

In the following we declare some simple tags and a numeric tag.

/** Tag giving semantic meaning that the element is a state. */
public static final SemanticFilterTag STATE = new SemanticFilterTag("state");
/** Tag giving semantic meaning that the element is final. */
public static final SemanticFilterTag FINAL = new SemanticFilterTag("final");

/** Returns a tag giving semantic meaning how many declarations an element has. */
public static SemanticFilterTag DECLARATIONS(Double num) {
    return new SemanticFilterTag("numDeclarations", num);
}

/** Returns a tag giving semantic meaning how many declarations an element has without a value.
 * Used for constructing rules involving the tag.
 * /
public static SemanticFilterTag DECLARATIONS = new SemanticFilterTag("numDeclarations);

We can then assign these tags during the synthesis.

node.getProperty(KlighdProperties.SEMANTIC_FILTER_TAGS).add(SCChartsSemanticFilterTags.STATE)
...
node.getProperty(KlighdProperties.SEMANTIC_FILTER_TAGS).add(SCChartsSemanticFilterTags.DECLARATIONS(filteredDeclarations.size as double)) 

Next, we need some rules that we can use to filter elements on the client.in

/** Rule to exclude elements that are states. */
public static final SemanticFilterRule NO_STATES = new NegationConnective(SCChartsSemanticFilterTags.STATE, "Filter States");

/** Rule to only include elements that have at least 3 declarations. */
public static final SemanticFilterRule ONLY_AT_LEAST_3_DECLARATIONS = new OrConnective(
    new LessEqualsConnective(new NumericConstantConnective(3.0), SCChartsSemanticFilterTags.DECLARATIONS
    "Filter Elements With Less Than 3 Declarations");

Finally we can add the rules to the graph (here we add them to the root node) [xtend].

rootNode.setProperty(KlighdProperties.SEMANTIC_FILTER_RULES, #[NO_STATES, ONLY_AT_LEAST_3_DECLARATIONS])

Expression language for creating filter rules

In addition to the programmatic method of defining rules an expression language may be used. SemanticFilterRuleParserUtil.parse(<ExpressionString>) may be used to parse these expressions and obtain the corresponding SemanticFilterRule.

Expressions are built up analogously to the programmatic construction. Each expression is evaluated either to a boolean or numeric value. An atomic expression is either a constant (true, false or a string that can be parsed as Java double) or a tag variable. A tag variable consists of a string identifier (without whitespaces) and is preceded by # to denote a boolean value i.e. the tag is present or not or by a $ to denote a numeric value. Whitespaces are used as separators between operators and expressions. The table below gives an overview over the available operators. Brackets ((,)) may additionally be used to override precedence.

Operator Syntax Input Output Precedence
And <expr> && <expr> boolean boolean 4
Or <expr> || <expr> boolean boolean 3
Not ! <expr> boolean boolean 6
Addition <expr> + <expr> numeric numeric 9
Subtraction <expr> - <expr> numeric numeric 9
Multiplication <expr> * <expr> numeric numeric 10
Division <expr> / <expr> numeric numeric 10
GreaterEquals <expr> >= <expr> numeric boolean 8
GreaterThan <expr> > <expr> numeric boolean 8
LessEquals <expr> <= <expr> numeric boolean 8
LessThan <expr> < <expr> numeric boolean 8
Equals <expr> = <expr> numeric/boolean boolean 7
NotEqual <expr> != <expr> numeric/boolean boolean 7
Valid example expressions
  • #initial || $regions >= 3 - keeps all elements that have the tag initial or have the tag regions with a value of 3 or higher.
  • $children + $importance > $weight - keeps all elements where the sum of the children and importance tags is higher than the value of the weight tag

Evaluating rules on the client

How exactly a feature on the client uses these tags and rules is flexible. In general the rules should be retrieved from the graph and some decision must be made on how to choose a rule based on its name. Then rules can be applied on graph elements, which allows filtering of elements.

Getting filters from the root

import { Filter, getFilters } from "../../filtering/semantic-filtering-util";
...
filters: Filter[] = getFilters(rootNode)

Filter interface

export interface Filter {
    name?: string
    defaultValue?: boolean
    filterFun(el: SKGraphElement): boolean
}

Now using a list of graph elements we can use the filter function to apply this Filter to all graph elements and get a filtered list of graph elements.

@Eddykasp Eddykasp added enhancement New feature or request LSP Affect the klighd language server. requires client change This change is linked to some change on the client side implementation in klighd-vscode labels Jul 25, 2022
Copy link
Member

@NiklasRentzCAU NiklasRentzCAU left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As all of this (and the client changes) are very generic and do not do anything currently, some documentation how to use this, some tests, or simple examples should be added to show what this does.

@Eddykasp
Copy link
Contributor Author

As all of this (and the client changes) are very generic and do not do anything currently, some documentation how to use this, some tests, or simple examples should be added to show what this does.

I've updated the PR description with a small usage guide and some simple examples. This could later be moved to the wiki for developers.

@Eddykasp
Copy link
Contributor Author

Eddykasp commented Sep 4, 2023

superseded by #129

@Eddykasp Eddykasp closed this Sep 4, 2023
@Eddykasp Eddykasp deleted the mka/semantic-filtering-v2 branch September 12, 2023 08:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request LSP Affect the klighd language server. requires client change This change is linked to some change on the client side implementation in klighd-vscode
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants