DeepAI

Formal Semantics of the Kconfig Language

The Kconfig language defines a set of symbols that are assigned a value in a configuration. We describe the semantics of the Kconfig language according to the behavior exhibited in the xconfig configurator. We assume an abstract syntax representation for concepts in the Kconfig language and delegate the details of the translation from concrete to abstract syntaxes to a later document.

• 2 publications
• 14 publications
07/02/2021

Formal Semantics of a Classical-Quantum Language

We investigate the formal semantics of a simple imperative language that...
09/23/2022

Formal Semantics of the CDL Language

We reverse-engineer a formal semantics of the Component Definition Langu...
05/04/2019

An experiment with denotational semantics

The paper is devoted to showing how to systematically design a programmi...
02/04/2021

Operational Semantics with Hierarchical Abstract Syntax Graphs

This is a motivating tutorial introduction to a semantic analysis of pro...
10/18/2021

Semantic network analysis of abstract and concrete word associations

In recent years, a new interest for the use of graph-theory based networ...
09/20/2021

Intensionalizing Abstract Meaning Representations: Non-Veridicality and Scope

Abstract Meaning Representation (AMR) is a graphical meaning representat...
08/24/2019

1 Abstract syntax

Identifiers and expressions.

We start be defining the preliminary concepts available in the Kconfig language. Let Id be a finite set of names identifying a symbol—more precisely, . Let be the set of values assignable to each feature and available as constants in expressions, where . Tri is ordered such that . The Tri, String, Hex, and Int domains are disjoint (i.e. mutually exclusive). We can now define an expression in the Kconfig language. is a set of expressions over Id generated by the following grammar, where , , , :

 e::=e⊗e∣note∣iv⊖iv∣iv (1)

Evaluating a KExpr returns a tristate value (i.e. ). We will define the semantics of an function in Section 2.2.

Kconfig model.

Kconfig denotes the set of all possible models in the Kconfig language. Thus a single Kconfig model is a tuple consisting of a set of configs and a set of choices. Kconfig is defined as:

 Kconfig=P(Configs)×P(% Choices) (2)

Given a Kconfig model , we define the shorthand  to refer to its set of configs and  to refer to its set of choices.

Configs are the primary components of a Kconfig model. A config defines a unique identifier with type, a prompt condition — a condition that determines when a config becomes user-changeable, a list of defaults, a expression denoting its reverse dependency — the conditions that would forcefully enable this feature through a select statement, and a set of ranges — restrictions on the value for configs or hex type. We define Configsas follows:

 Configs=Id×Type×KExpr(Id% )×Default∗×KExpr(Id)×P(Range) (3)

where,

• denotes a type and consequently the possible values for the config.

• denotes defaults. The first KExprdenotes a default expression (i.e. that is evaluated and assigned to the symbol) and the second KExprdenotes the condition required for the default to become effective.

• is a triple consisting of a lower bound, an upper bound and a condition. Note the absence of Tri in the lower and upper bounds of the range; this is due to ranges being only effective on int and hex-typed configs as we will describe in the following paragraph.

We further define a function to denote identifiers of configs in the model :

 Id(m)={n∣(n,_,_,_,_,_)∈mconfig} (4)

The second component of Kconfig refers to a set of choice nodes. A choice is an abstract construct that defines no symbol in the configuration, however, it imposes additional constraints on its nested elements. We define choices as a quadruple consisting of a type where boolean or tristate are the only valid types, a flag indicating whether the choice is mandatory, a prompt condition followed by a set of identifiers indicating its members. The set Choices is defined as:

 Choices={boolean,tristate}×Bool×KExpr(Id)×P(Id(m)) (5)

Well-formedness rules.

Given an element , this config is well-formed if the following conditions are satisfied:

• The reverse dependency of configs with type int, hex or string must be . In other words, no config may select a config that is not of type boolean or tristate.

 (rev≠0t)⟹t=boolean∨t=tristate (6)
• Ranges can only be defined on configs with a numerical type, namely int or hex types. Thus, the following constraint must hold for a config to be well-formed:

 (|rngs|>0)⟹t=int∨t=hex (7)

Brief note on concrete syntax translation.

Menuconfigs and menus are first-class concepts in the concrete syntax of the Kconfig language. However, both of these concepts are not present in the abstract syntax. First, menuconfigs are semantically identical to configs and only differ in terms of its appearance in the configurator; thus, we model menuconfigs as configs in the abstract syntax. Menus do not define a symbol; thus menus are not present in a configuration. However, menus can impose constraints on its nested elements. We handle these constraints via a syntactic rewrite on the prompt, default and range conditions of all nested symbols. Details for this syntactic rewrite will be provided in later document.

2 Semantics

2.1 Semantic domain

A configuration of a Kconfig model is an assignment of values to config elements. Thus, the set of all possible configurations is defined as:

 Confs=Id→⌊Const⌋ (8)

If and , we write in order to refer to the value of identifier under the configuration . Now, we define the semantics of a Kconfig model in terms of sets of configurations. Thus,  is our semantic domain. We define as the function that evaluates a Kconfig model and returns a set of valid configurations:

 [[⋅]]kconfig:Kconfig→P(Confs) (9)

2.2 Global functions

We start with the definition of some functions used throughout the semantics. First, we define an interpretation of tristate values in boolean logic with where :

 bool(v)={Fiff~{}v=0tTiff~{}v=1t∨v=2t (10)

Moreover, we define a function that retrieves the value of either a constant or a symbol. When an identifier has the value of (to be defined in Equation 14), then the function returns the identifier itself in the form of a string:

 access(iv,c)={iviff~{}iv∈Const∨(iv∈Id∧c(iv)=⊥)c(iv)otherwise (11)

Next, we define the function that models the translation of a constant to a string representation. Let , and , in the following definition of :

 toStr(0t) =n'' toStr(1t) =m'' toStr(2t) =y'' (12) toStr(i) =''+i toStr(h) =0x''+h toStr(s) =s

where the operator is string concatenation.

Finally, the function describes the evaluation of a in the Kconfig language. We define recursively with and :

 (13)

2.3 Valuation functions

Kconfig model.

We begin by defining the . Given a Kconfig model , the semantics of a model is the intersection of all denotations across the model, configs and choices. In other words, the set of valid configurations for a Kconfig model is those configurations that satisfy all denotations. is defined:

 [[m]]kconfig=⎛⎝⋂n∈mconfig[[n]]type∩[[n]]bounds∩[[n]]default∩[[n]]range⎞⎠∩(⋂n∈mchoice[[n]]choice)∩[[m]]module∩[[m]]undeclared (14)

Type.

The first denotation pertains to the constraints imposed by a config’s type. The type of a config restricts its valid values to those in its respective domain. is defined:

 [[(n,t,_,_,_,_)]]type=⎧⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪⎨⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪⎩{c∈% Confs∣c(n)∈Tri∖{1t}}iff t=boolean{c∈Confs∣c(n)∈Tri}iff t=%tristate{c∈Confs∣c(n)∈String}iff t=string{c∈Confs∣c(n)∈Hex∪{''}}iff t=hex{c∈Confs∣c(n)∈Int∪{''}}iff t=int (15)

Upper and lower bounds.

Next, the bounds denotation models the lower and upper bounds of a config. The lower bound is determined by the evaluation of a config’s reverse dependency. Recall that the reverse dependency models the behaviour of the select statement in the concrete syntax. The upper bound is defined by a config’s prompt condition. This denotation has no effect on configs of type int, hex, or string since the the reverse dependency that determines a lower bound is by our well-formedness rules, and the function returns when evaluating a value not in Tri. is defined:

 [[(n,_,pro,_,rev,_)]]bounds={c∈Confs∣eval(c(n),c)≥Lower(c)∧(Upper(c)

where Lower(c) = eval(rev,c) and Upper(c) = eval(pro,c).

Defaults.

Kconfig has support for setting a default expression for a config. The default expression interacts with the prompt condition that determines when the config is user-changeable. When the prompt condition is satisfied, then the user is free to set a value. However, when the prompt condition is not satisfied, the default determine the config’s value. is defined:

 [[(n,_,_,defs,rev,_)]]default={c∈Confs∣bool(eval(pro,c))∨c(n)=max(eval(default(defs,c)),eval(rev,c))} (17)

where is a function that models the retrieval of a default. Recall that is a list of defaults (and thus ordered). The effect of a default’s value depends on the type of its defining config. If the config is or , then the default value is evaluated to a value in Tri. Otherwise, the default value must be either an element of Const or Id. Let be the empty list and be the list operator. Let and . The function is defined recursively, so we begin by defining its base cases:

 default(Nil,tTri,c) =0t (18) default(Nil,tEntry,c) =\,''

Equation 18 states that given an empty list of defaults, we return if the type is either boolean or tristate, or the empty string for types int, hex or string. Next, we define the recursive rule. In the following equation, we decompose the list into its head and tail components. First, we describe the function for boolean and tristate type:

 default((e,cond)::rest,tTri,c)={eval(e,c)if~{}bool(eval(cond,c))default(rest,tTri,c)otherwise (19)

Now for the remaining types:

 default((e,cond)::rest,tEntry,c)={access(e,c)if~{}bool(eval(cond,c))default(rest,tEntry,c)otherwise (20)

Ranges.

Ranges impose a lower and upper bound on the value of int or hex configs. is defined as:

 [[n,_,_,_,_,rngs)]]range={c∈Confs∣ ∀(l,u,cond)∈rngs.bool(eval(cond,c))→c(n)≥access(l,c)∧c(n)≤access(u,c)} (21)

Choices.

A choice restricts the number of members that can be selected (i.e. have a value greater than ). The choice denotation, is defined:

 [[(boolOrTri,isMand,prompt,mems)]]choice={c∈Confs∣ bool(eval(prompt,c))→% Xor∧BChoice∧Mandatory} (22)

where Xor defines the condition that one and only one member may be set to :

 Xor=∃m1∈mems. (m1=2t)→(∀m2∈mems∖{m1}. m2=0t) (23)

If the choice is a boolean choice, then the only valid value for its members is . In combination with Xor, this defines that a boolean choice may have at most one member with a value not equal to and that member must be set to :

 BChoice=(boolOrTri=boolean)→∃m∈mems. c(m)=2t (24)

Finally, if the choice is mandatory, then at least one member must be selected:

 Mandatory=isMand→∃m∈mems. c(m)>0t (25)

Modules.

A special modules config is used to specify support for modules in the kernel. Disabling modules disallows the state for configs and effectively turns all tristate configs into boolean configs. A special symbol is used in expressions to identify a dependency on the modules feature in the concrete syntax. Configs with a dependency on cannot be selected (i.e. must be set to ) if modules is not selected. We assume that the special identifier has been expanded to modules in the abstract syntax.

 [[m]]module={c∈Confs∣c(\textscmodules)=n→∀i∈Id. c(i)≠1t} (26)

Undeclared symbols.

We also define the behaviour of undeclared symbols. The Kconfig language supports references to symbols that are not declared in constraints. These undeclared symbols are assigned the special symbol in our semantics. The use of this symbol will become apparent in the definition of the function in Section 2.2. The denotation is defined as:

 [[m]]undeclared={c∈Confs∣∀x∈Id% ∖Id(m). c(x)=⊥} (27)

3 1-Var Propositional Semantics

The goal of the propositional semantics is to achieve a weakening of the constraints of the full semantics.

Rewrite rules for expressions.

The is a partial function that implements rewrite rules on expressions. The function is defined as:

 rewrite(e)=⎧⎪ ⎪ ⎪⎨⎪ ⎪ ⎪⎩0if~{}(e is an variable ∧typeOf(e)∈{int,hex,string})∨e=0t1if~{}e=1t∨e=2tX↔Yif~{}e is X=Y where X and Y are % variables{Use Table~{}???}if~{}e is X=lit∨X≠lit (28)

We further define the function which converts an expression to CNF and removes clauses equivalent to equality checks. This function is used to relax the constraints on the antecedent (LHS) of an implication.

Semantics.

In the propositional semantics, we model the set of propositional configurations as :

 Confsp=Id→Bool (29)

The function is defined as . An extra parameter providing the declaring identifier is needed for the propositional semantics.

 default(n,defs,c)=⎧⎪ ⎪ ⎪⎨⎪ ⎪ ⎪⎩¬nif no default conditions are % satisfiedrewrite(n=eval(ivi,c))otherwise if~{}t∈{boolean,tristate},where ivi is the 1st matching default valuenotherwise if~{}t∈{int,hex,string} (30)

The default denotation is defined as:

 [[(n,t,vis,pro,defs,rev,rngs)]]default={c∈Confsp∣eval(pro,c)∨default(n,defs,c)} (31)

The constraint denotation which models constraints imposed by the reverse dependency and visibility conditions is defined as:

 [[(n,t,vis,pro,defs,rev,rngs)]]bounds={c∈Confsp∣(eval(relax(rev),c)→c(n))∧(c(n)→eval(vis,c))} (32)

We ignore ranges since we abstract away the value of each config. We also assume that the module config is enabled, thus allowing for the state in tristate configs.

 [[(boolOrTri,isMand,vis,mems)]]choice={c∈Confs∣eval(vis,c)→choose(1,ids(mems))∧(isMand→⋁m∈memsm)} (33)