1 Introduction

Membrane Computing, since its beginnings [1], has covered a wide spectrum of applications, from computability theory [2] and computational complexity theory [3] to pandemics [4] and engineering [5]. The model is inspired in the structure and behavior of living cells and the chemical reactions occurring within them. From the beginning, solving computationally hard problems has been a hot topic in this area [6], being one of the most studied fields with membrane systems.

Cell-like P systems can be seen as a hierarchical structure of membranes that let chemical compounds pass by them. Making an abstraction of integral membrane proteins and their role in the transport of molecules, symport/antiport rules let objects move to one region to other one or interchange them between two regions [7]. Usually, P systems are found to be Turing complete [8], but from the point of view of the computational complexity theory, they can only solve problems from the class \({\textbf {P}}\) [9]. To increase the efficiency of these systems, different types of rules have been introduced: division rules [6], separation rules [10] and creation rules [11] are three of the protocols that have been implemented in membrane computing with this purpose. The latter uses a single object and transforms it into a new membrane.

In the framework of cell-like membrane systems, creation rules have been used lately besides evolutional communication rules in [12] to solve the SAT problem by means of a family of recognizer P systems with evolutional communication rules and creation rules. In [13], an efficient solution to QSAT is given by means of a family of recognizer polarizationless P systems with active membranes and membrane creation, and in [14], an efficient solution to QSAT is given by means of a family of P systems with evolutional symport/antiport rules of length (1, 1) and creation rules. Creation rules have not been used in P systems with classical symport/antiport rules. In this work, we try to replicate the results of the latter paper using recognizer P systems with classical symport/antiport rules with a minimal amount of objects per communication rule. This is a really important result, since evolutional communication rules are intrinsically changing the nature of the objects, and thus both in a software simulation and in real-life implementations, it would need to implement these changes in some sense, leading to a more complex implementation. That is why the use of classical symport/antiport rules is really interesting in order to reduce the “number of ingredients” (we could think that the evolution part of evolutional symport/antiport rules is an ingredient) of the P systems using these rules.

The rest of the work is organized as follows: Section 2 is devoted to introduce some formal language and set theory concepts used later through the paper. In Sect. 3, the definition of recognizer P systems with symport/antiport rules and membrane creation is given. In the following section, a polynomial-time and uniform solution to QSAT is given by means of a family of recognizer P systems with symport/antiport rules of length at most 1 and membrane creation, and an overview of the computations and the formal verification of the design are specified. Finally, some remarks and open research lines are indicated.

2 Preliminaries

Some basic notions of formal languages, set theory and other terms used throughout the paper are recalled in this section. For a deeper explanation on formal languages and membrane computing, we refer the reader to [15, 16].

An alphabet \(\Gamma \) is a non-empty set, and its elements are called symbols. A string u over \(\Gamma \) is a finite sequence of symbols from \(\Gamma \). The number of appearances of a symbol a in u is denoted by \(\mid u \mid _{a}\). The length of u, denoted by \(\mid u \mid \) is \(\sum _{a \in u} \mid u \mid _{a}\).

A multiset over \(\Gamma \) is a pair \((\Gamma , f)\) where \(f : \Gamma \rightarrow {\mathbb {N}}\) is a mapping from \(\Gamma \) to the set of natural numbers \({\mathbb {N}}\). Let \(m_{1} = (\Gamma _{1}, f_{1}), m_{2} = (\Gamma _{2}, f_{2})\) two multisets over \(\Gamma \). The union of \(m_{1}\) and \(m_{2}\), denoted by \(m_{1} + m_{2}\) or \(m_{1} \cup m_{2}\) is defined as \((f_{1} + f_{2})(x) = f_{1}(x) + f_{2}(x)\). The relative complement of \(m_{2}\) in \(m_{1}\), denoted by \(m_{1} \setminus m_{2}\), is the defined as

$$\begin{aligned} (m_{1} \setminus m_{2})(x) = \left\{ \begin{array}{ll} f_{1}(x) - f_{2}(x) &{} \text{ if } f_{1}(x) \ge f_{2}(x) \\ 0 &{} \text{ if } f_{1}(x) < f_{2}(x). \end{array} \right. \end{aligned}$$

The empty multiset is denoted by \(\emptyset \), and the set of all finite multisets over \(\Gamma \) is denoted by \(M_{f}(\Gamma )\).

The size of the set u is given by the total number of objects in u, and it is denoted by \(\mid u \mid \).

The Cantor pairing function \(\langle \cdot , \cdot \rangle \) is a bijective function defined as \(\langle a, b\rangle = \frac{(a+b+1)(a+b)}{2}+b\).

3 Recognizer P systems with symport/antiport rules and creation rules

In this section, a definition of recognizer P systems with symport/antiport rules and creation rules is given, and both the syntax and semantics are recalled.

Definition 1

A recognizer P system with symport/antiport rules and membrane creation of degree \(q \ge 1\) is a tuple

$$\begin{aligned} \Pi = (\Gamma , \Sigma , \mathcal {E}, H, \mu , \mathcal {M}_{1}, \ldots , \mathcal {M}_{q}, \mathcal {R}_{1}, \ldots , \mathcal {R}_{q}, i_{in}, i_{out}), \end{aligned}$$

where

  1. 1.

    \(\Gamma \), \(\Sigma \) and \(\mathcal {E}\) are finite alphabets of objects, where \(\Sigma , \mathcal {E} \subseteq \Gamma , \Sigma \cap \mathcal {E} = \emptyset \);

  2. 2.

    H is a finite set of labels;

  3. 3.

    \(\mu \) is a membrane structure whose elements are injectively labeled by elements of H;

  4. 4.

    \(\mathcal {M}_{i}, 1 \le i \le q\) are finite multisets over \(\Gamma \setminus (\Sigma \cup \mathcal {E})\);

  5. 5.

    \(\mathcal {R}\) is a set of rules of the following forms:

    • Symport rules:

      • \((u, in) \in \mathcal {R}_{i}\), where \(u \in M_{f}(\Gamma )\), except if i is the skin membrane, where \(u \in M_{f}(\Gamma ) \wedge u \not \in M_{f}(\mathcal {E})\) (send-in rules);

      • \((u, out) \in \mathcal {R}_{i}\), where \(u \in M_{f}(\Gamma )\) (send-out rules);

    • Antiport rules:

      • \((u, out; v, in) \in \mathcal {R}_{i}\), where \(u, v \in M_{f}(\Gamma )\);

    • Creation rules: \({[} \, a \rightarrow {[} \, u \, ]_{i} \, ]_{j}\), where \(i, j \in H, i \not \in \{skin, i_{out}\}\), where skin is the label of the skin membrane, \(a \in \Gamma , u \in M_{f}(\Gamma )\);

  6. 6.

    \(i_{in} \in H\) is the label of the input membrane;

  7. 7.

    \(i_{out} = env\) is the label of the output zone, in this case, the environment.

A configuration \(C_{t}\) of a P system with symport/antiport rules and creation rules is described by the membrane structure at the moment t and the multisets of objects over \(\Gamma \) of each membrane, and the multiset of objects over \(\Gamma \setminus \mathcal {E}\) of the environment. We use the term region i to refer to a membrane if \(i \in H\) and to the environment if \(i = env\). We can suppose that in each moment, there is an arbitrary number of objects from \(\mathcal {E}\) in the environment. Let m be the input multiset encoding the corresponding instance of a problem. The initial configuration is of such a P system \(\Pi \) is \(\mathcal {C}_{0} = (\mu , \mathcal {M}_{1}, \ldots , \mathcal {M}_{i_{in}} + m, \ldots , \mathcal {M}_{q}; \emptyset )\).

A symport rule \((u, in) \in \mathcal {R}_{i}\), called send-in rule, can be applied to a configuration \(C_{t}\) if there exists a membrane labeled by i, and the parent region contains a multiset of objects u. When applying such a rule, the multiset of objects u is consumed from the parent region and a multiset of objects u is produced in the membrane i in the next configuration.

A symport rule \((u, out) \in \mathcal {R}_{i}\), called send-out rule, can be applied to a configuration \(C_{t}\) if there exists a membrane labeled by i that contains a multiset of objects u. When applying such a rule, the multiset of objects u is consumed from the membrane i and a multiset of objects u is produced in the parent region.

An antiport rule \((u, out; v, in) \in \mathcal {R}_{i}\) can be applied to a configuration \(C_{t}\) if there exists a membrane labeled by i that contains a multiset of objects u, and whose parent region contains a multiset of objects v. When applying such a rule, the multisets of objects u and v are consumed from the membrane i and its parent region, respectively, and multisets v and u are produced in the membrane i and its parent region, respectively.

A creation rule \({[} \, a \rightarrow {[} \, u \, ]_{i} \, ]_{j}\) can be applied to a configuration \(C_{t}\) if there exists a membrane labeled by j that contains an object a. When applying such a rule, object a is consumed from membrane j and a new membrane labeled by i and containing the multiset of objects u appears as a child membrane of j.

A recognizer P system with symport/antiport rules and creation rules that does not send objects from the environment to the system is said to be a P system with symport/antiport rules and creation rules without environment. In this case, the set of objects of the environment \(\mathcal {E}\) is usually not defined in the tuple.

A transition of a P system \(\Pi \) is defined as a computational step of \(\Pi \), passing from one configuration to the next one, and denoted by \(C_{t} \Rightarrow _{\Pi } C_{t+1}\). A computation of a P system is a sequence of configurations such that a configuration \(C_{t+1}\) is always obtained from \(C_{t}\) by applying a computation step. \(C_{0}\) is the initial configuration of \(\Pi \).

In [17, 18], the semantics applied are maximalist in the following sense: In each membrane, an arbitrary number of creation rules can be applied, and they do not interfere with the application of other types of rules. In [12, 13], more restrictive semantics were introduced. When a creation rule is applied in a membrane h, no other rules can be applied in the same computational step. In this case, dealing with P systems with symport/antiport rules and membrane creation, either communication rules in a maximal parallel way or a single creation rule can be applied in a membrane in a transition, but not both at the same time. That is, if a creation rule \({[} \, a \rightarrow {[} \, b \, ] \, ]_{h}\) is applied, then neither other creation rules in that membrane h nor other symport/antiport rules from \(\mathcal {R}_{h}\). In this paper, the latter semantics, called minimalist semantics are going to be used. As a recognizer membrane system, all the computations of a recognizer P system with communication rules and creation rules halt and either an object \(\mathtt {yes}\) or an object \(\mathtt {no}\) (but not both) is sent to the environment at the last step of the computation.

The length of a symport rule \(r \equiv (u, in)\) or \(r \equiv (u, out)\) is given by the number of objects in multiset u; that is, it is equal to \(\mid u \mid \). The length of an antiport rule \(r \equiv (u, out; v, in)\) is given by the total number of objects in the rule; that is, it is equal to \(\mid u \mid + \mid v \mid \). Let us denote the length of a rule r by l(r).

The class of all recognizer P systems with symport/antiport rules and membrane creation of degree q is denoted by \(\mathcal {C}\mathcal {C}\mathcal {C}(k)\) with minimalistic semantics, where k represents the maximal number of objects in a communication rule; that is, \(k = max({l(r) \mid r \in \mathcal {R}_{i}, 1 \le i \le q})\). The class of recognizer membrane systems of this type when environment plays a passive role; that is, when no objects can be sent from the environment to the P system itself, is denoted by \(\widehat{\mathcal {C}\mathcal {C}\mathcal {C}}(k)\).

All the concepts of a decision problem and the class of decision problems that can be solved by means of a uniform family of membrane systems from \(\mathcal {C}\mathcal {C}\mathcal {C}(k)\) can be extracted from [12, 15, 19]. The class of problems that can be solved efficiently (i.e., in polynomial time with respect to the input) by means of a uniform family of recognizer P systems with symport/antiport rules of length at most k and membrane creation with environment (respectively, without environment) is denoted by \({\textbf {PMC}}_{\mathcal {C}\mathcal {C}\mathcal {C}(k)}\) (resp., \({\textbf {PMC}}_{\widehat{\mathcal {C}\mathcal {C}\mathcal {C}}(k)}\)).

4 An efficient solution to \(\mathtt {QSAT}\) in \(\widehat{\mathcal {C}\mathcal {C}\mathcal {C}}(1)\)

In this section, we give an efficient solution to the \(\mathtt {QSAT}\) problem by means of a uniform family \({{\varvec{\Pi }}}\) of P systems from \(\widehat{\mathcal {C}\mathcal {C}\mathcal {C}}(1)\). Let \(t = \langle n, p\rangle \). Each P system \(\Pi (t), t \in {\mathbb {N}},\) from \({{\varvec{\Pi }}}\) solves all instances from \(\mathtt {QSAT}\) with n variables and p clauses.

For each pair \(n, p \in {\mathbb {N}}\), we consider a recognizer P system with symport/antiport rules of length 1 and creation rules

$$\begin{aligned} \Pi (\langle n, p \rangle ) = (\Gamma , \Sigma , H, \mu , \mathcal{M}_{skin}, {{\mathcal {M}}}_{\alpha }, {{\mathcal {R}}}, i_{in}, i_{out}) \end{aligned}$$

that will solve all instances with n variables and p clauses, where \(\varphi ^{*} = \exists x_{1} \forall x_{2} \ldots Q_{n} x_{n} \varphi (x_{1}, \ldots , x_{n})\) is an existential fully quantified formula associated with a Boolean formula \(\varphi (x_{1}, \ldots , x_{n}) \equiv C_{1} \wedge \ldots \wedge C_{p}\) in CNF, where each clause \(C_{j} = l_{j,1} \vee \ldots \vee l_{j, r_{j}}\), \(Var(\varphi ) = \{x_{1}, \ldots , x_{n}\}\) and \(l_{j, k} \in \{x_{i}, \lnot x_{i} \mid 1 \le i \le n\}\). Let us suppose that the number of variables, n, and the number of clauses, p, is at least 2. We consider a polynomial encoding (cods) from \(\mathtt {QSAT}\) in \({{\varvec{\Pi }}}\) as follows: for each formula \(\varphi \) associated with an existential fully quantified formula \(\varphi ^{*}\) with n variables and p clauses, \(s(\varphi ) = \langle n, p\rangle \) and \(cod(\varphi ) = \{x_{i,j} \mid x_{i} \in C_{j}\} \cup \{\overline{x}_{i,j} \mid \lnot x_{i} \in C_{j}\}\) and \(s(\varphi ) = \langle n,p\rangle \)

  1. 1.

    The working alphabet is defined as follows:

    \(\Gamma = \Sigma \cup \{ \mathtt{yes}, \mathtt{no}, d', d'_{t}, d'_{f}, d'' \} \cup \{ \alpha _{i} \mid \, 0 \le i \le n^{2} \cdot p + 5n + 2p + 3 \} \cup \{ \alpha '_{i} \, \mid \, 0 \le i \le n^{2} \cdot p + 5n + 2p + 4 \} \cup \{ c_{i,j,r} \, \mid \, 1 \le i \le n, 1 \le j \le p, r \in \{t, f\}\} \cup \{ d_{i,r} \, \mid \, 0 \le i \le n, r \in \{t, f\}\} \cup \{ z_{i}, z_{i,t}, z_{i,f} \, \mid \, 1 \le i \le n \} \cup \{ x_{i',i,j,t}, \overline{x}_{i',i,j,f} \, \mid \, 1 \le i, i' \le n, 1 \le j \le p\}\).

  2. 2.

    The input alphabet \(\Sigma = \{ x_{i,j}, \overline{x}_{i,j} \, \mid \, 1 \le i \le n, 1 \le j \le p\}\).

  3. 3.

    \(H = \{skin, 1, \dots , p, yes, no, \#\} \cup \{ \langle i,r\rangle \mid \, 0 \le i \le n, r \in \{t, f\} \} \cup \{\langle i,Q,r,r'\rangle \mid \, 0 \le i \le n, Q \in \{\exists , \forall \}, r, r' \in \{t, f\} \} \cup \{\langle i,\#\rangle \mid \, 0 \le i \le n^{2} \cdot p + 5n + 2m + 4\}\).

  4. 4.

    \(\mu = {[} \, [\quad ]_{\alpha } \, ]_{skin}\).

  5. 5.

    \({{\mathcal {M}}}_{skin} = \{z_{1,t}, z_{1,f}\}, {{\mathcal {M}}}_{\alpha } = \{\alpha _{0}, \alpha '\}\).

  6. 6.

    The set of rules \(\mathcal {R}\):

    1. 6.1

      Rules for the counter of the elements of membrane \(\alpha \); let \(k = n^{2}p + 13n + 5p + 2\)

      \( \left. \begin{array}{l} {[} \, \alpha _{i} \rightarrow {[} \, \alpha _{i+1} \, ]_{\#} \, ]_{\alpha } \end{array} \right. \text{ for } 0 \le i \le \lfloor k / 2 \rfloor - 1\)

      \( \left. \begin{array}{l} (\alpha _{i}, out) \in \mathcal {R}_{\#} \end{array} \right. \text{ for } 0 \le i \le \lfloor k / 2 \rfloor \)

      \( \left. \begin{array}{l} {[} \, \alpha _{\lfloor k / 2 \rfloor } \rightarrow {[} \, \alpha \, ]_{\alpha '} \, ]_{\alpha } \\ (\alpha , out) \in \mathcal {R}_{\alpha '} \\ (\alpha , out) \in \mathcal {R}_{\alpha } \\ (\alpha ', in) \in \mathcal {R}_{\alpha '} \\ {[} \, \alpha \rightarrow {[} \, \alpha '' \, ]_{\#} \, ]_{\alpha '} \\ (\alpha '', out) \in \mathcal {R}_{\#} \\ (\alpha '', out) \in \mathcal {R}_{\alpha '} \\ (\alpha '', out) \in \mathcal {R}_{\alpha } \end{array} \right. \)

    2. 6.2

      Rules to return a positive answer

      \( \left. \begin{array}{l} {[} \, D_{1,r} \rightarrow {[} \, \# \, ]_{yes} \, ]_{skin} \end{array} \right. \text{ for } r \in \{t, f\}\)

      \( \left. \begin{array}{l} (\alpha , in) \in \mathcal {R}_{yes} \\ {[} \, \alpha \rightarrow {[} \, \mathtt {yes} \, ]_{\#} \, ]_{yes} \\ (\mathtt {yes}, out) \in \mathcal {R}_{\#} \\ (\mathtt {yes}, out) \in \mathcal {R}_{yes} \\ (\mathtt {yes}, out) \in \mathcal {R}_{skin} \end{array} \right. \)

    3. 6.3

      Rules to return a negative answer

      \( \left. \begin{array}{l} {[} \, \alpha '' \rightarrow {[} \, \# \, ]_{no} \, ]_{skin} \\ (\alpha , in) \in \mathcal {R}_{no} \\ {[} \, \alpha \rightarrow {[} \, \mathtt {no} \, ]_{\#} \, ]_{no} \\ (\mathtt {no}, out) \in \mathcal {R}_{\#} \\ (\mathtt {no}, out) \in \mathcal {R}_{no} \\ (\mathtt {no}, out) \in \mathcal {R}_{skin} \end{array} \right. \)

    4. 6.4

      Rules to generate the membrane structure

      \( \left. \begin{array}{l} {[} \, z_{1, r} \rightarrow {[} \, z_{1} \, d_{\forall } \, ]_{\langle 1, r\rangle } \, ]_{skin} \end{array} \right. \text{ for } r \in \{t, f\}\)

      \( \left. \begin{array}{l} {[} \, z_{i, r} \rightarrow {[} \, z_{1} \, d_{\exists } \, ]_{\langle i, r\rangle } \, ]_{\langle i-1, r' \rangle } \end{array} \right. \text{ for } 3 \le i \le n - 1, i \text{ odd } , r, r' \in \{t, f\}\)

      \(\left. \begin{array}{l} {[} \, z_{1,r} \rightarrow {[} \, z_{1} \, d'' \,]_{\langle 1,r\rangle } \, ]_{skin} \, \text{ for } \, r \in \{t, f\} \\ {[} \, z_{i,r} \rightarrow {[} \, z_{i} \, d' \,]_{\langle i,r\rangle } \, ]_{\langle i-1,r'\rangle } \, \text{ for } \, 2 \le i \le n, i \text{ odd }, r,r' \in \{t, f\} \\ {[} \, z_{i,r} \rightarrow {[} \, z_{i} \, d'' \,]_{\langle i,r\rangle } \, ]_{\langle i-1,r'\rangle } \, \text{ for } \, 2 \le i \le n, i \text{ even }, r,r' \in \{t, f\} \\ {[} \, z_{i} \rightarrow {[} \, z_{i+1,t} \, z_{i+1,f} \, ]_{\#} \,]_{\langle i,r\rangle } \, \text{ for } \, 1 \le i \langle n, r \in \{t, f\} \\ (z_{i,r}, out) \in \mathcal {R}_{\#} \, \text{ for } \, 1 \le i \le n, r \in \{t, f\} \end{array} \right. \)

    5. 6.5

      Rules to check which clauses are satisfied

      \(\left. \begin{array}{l} {[} \, x_{i,j} \rightarrow {[} \, x_{1,i,j,t} \, x_{1,i,j,f} \,]_{\#} \,]_{skin} \, \text{ for } \, 1 \le i \le n, 1 \le j \le p \\ {[} \, \overline{x}_{i,j} \rightarrow {[} \, \overline{x}_{1,i,j,t} \, \overline{x}_{1,i,j,f} \,]_{\#} \,]_{skin} \, \text{ for } \, 1 \le i \le n, 1 \le j \le p \\ {[} \, x_{i',i,j,r} \rightarrow {[} \, x_{i'+1,i,j,t} \, x_{i'+1,i,j,f} \,]_{\#} \,]_{\langle i'+1,r\rangle } \\ \text{ for } \, 1 \le i'< i \le n, 1 \le j \le p, r \in \{t, f\} \\ {[} \, \overline{x}_{i',i,j,r} \rightarrow {[} \, \overline{x}_{i'+1,i,j,t} \, \overline{x}_{i'+1,i,j,f} \,]_{\#} \,]_{\langle i'+1,r\rangle } \\ \text{ for } \, 1 \le i'< i \le n, 1 \le j \le p, r \in \{t, f\} \\ (x_{i',i,j,r}, out) \in \mathcal {R}_{\#} \\ \text{ for } \, 1 \le i'< i \le n, 1 \le j \le p, r \in \{t, f\} \\ (\overline{x}_{i',i,j,r}, out) \in \mathcal {R}_{\#} \\ \text{ for } \, 1 \le i'< i \le n, 1 \le j \le p, r \in \{t, f\} \\ (x_{i'+1,i,j,r}, in) \in \mathcal {R}_{\langle i'+1,r\rangle } \\ \text{ for } \, 1 \le i< i' \le n, 1 \le j \le p, r \in \{t, f\} \\ (\overline{x}_{i'+1,i,j,r}, in) \in \mathcal {R}_{\langle i'+1,r\rangle } \\ \text{ for } \, 1 \le i < i' \le n, 1 \le j \le p, r \in \{t, f\} \\ {[} \, x_{i,i,j,t} \rightarrow {[} \, c_{i,j,t} \, c_{i,j,f} \, ]_{\#} \,]_{\langle i,t\rangle } \, \text{ for } \, 1 \le i \langle n, 1 \le j \le p \\ {[} \, \overline{x}_{i,i,j,f} \rightarrow {[} \, c_{i,j,t} \, c_{i,j,f} \, ]_{\#} \,]_{\langle i,f\rangle } \, \text{ for } \, 1 \le i \langle n, 1 \le j \le p \\ {[} \, x_{n,n,j,t} \rightarrow {[} \, c_{n,j,t} \, ]_{\#} \, ]_{\langle n,t\rangle } \, \text{ for } \, 1 \le j \le p \\ {[} \, \overline{x}_{n,n,j,f} \rightarrow {[} \, c_{n,j,f} \, ]_{\#} \, ]_{\langle n,f\rangle } \, \text{ for } \, 1 \le j \le p \\ \end{array} \right. \)

      \(\left. \begin{array}{l} (c_{i,j,r}, out) \in \mathcal {R}_{\#} \, \text{ for } \, 1 \le i \le n, 1 \le j \le p, r \in \{t, f\} \\ (c_{i,j,r}, in) \in \mathcal {R}_{\langle i+1,r\rangle } \, \text{ for } \, 1 \le i \langle n, 1 \le j \le p, r \in \{t, f\} \\ {[} \, c_{i,j,r} \rightarrow {[} \, c_{i+1,j,t} \, c_{i+1,j,f} \, ]_{\#} ]_{\langle i',r\rangle } \\ \text{ for } \, 1 \le i' \le i < n, 1 \le j \le p, r \in \{t, f\} \end{array} \right. \)

    6. 6.6

      Rules to check if all clauses are satisfied

      \(\left. \begin{array}{l} {[} \, z_{n} \rightarrow {[} \, d_{0}]_{\#} \,]_{\langle n,r\rangle } \, \text{ for } \, r \in \{t, f\} \\ {[} \, c_{n,j,r} \rightarrow [\quad ]_{j} \, ]_{\langle n,r'\rangle } \, \text{ for } \, 1 \le j \le p, r, r' \in \{t, f\} \\ (d_{j}, in) \in \mathcal {R}_{j+1} \, \text{ for } \, 0 \le j< p, r \in \{t, f\} \\ {[} \, c_{n,j,r} \rightarrow [\quad ]_{j} \, ]_{\langle n,r\rangle } \, \text{ for } \, 1 \le j \le p, r \in \{t, f\} \\ {[} \, d_{j} \rightarrow {[} \, d_{j+1} \, ]_{\#} \, ]_{j+1} \, \text{ for } \, 0 \le j < p \\ (d_{j}, out) \in \mathcal {R}_{\#} \, \text{ for } \, 0 \le j \le p, r \in \{t, f\} \\ (d_{j}, out) \in \mathcal {R}_{j} \, \text{ for } \, 0 \le j \le p, r \in \{t, f\} \\ {[} \, d_{p} \rightarrow {[} \, d_{n,r} \,]_{\#} \, ]_{\langle n,r\rangle } \, \text{ for } \, r \in \{t, f\} \\ (d_{n,r}, out) \in \mathcal {R}_{\#} \, \text{ for } \, r \in \{t, f\} \end{array} \right. \)

    7. 6.7

      Rules to check if quantifiers are satisfied

      \(\left. \begin{array}{l} (d_{i,r}, out) \in \mathcal {R}_{\langle i,r\rangle } \, \text{ for } \, 1 \le i \le n, r, r' \in \{t, f\} \\ {[} \, d_{i+1,r} \rightarrow [\quad ]_{\langle i,\exists ,r,r'\rangle } \, ]_{\langle i,r'\rangle } \, \text{ for } \, 1 \le i< n, i \text{ odd }, r, r' \in \{t, f\} \\ {[} \, d_{i+1,r} \rightarrow [\quad ]_{\langle i,\forall ,r,r'\rangle } \, ]_{\langle i,r'\rangle } \, \text{ for } \, 2 \le i < n, i \text{ even }, r, r' \in \{t, f\} \end{array} \right. \)

      \(\left. \begin{array}{l} (d', in) \in \mathcal {R}_{\langle i,\exists ,r,r'\rangle } \, \text{ for } \, 1 \le i \le n, i \text{ odd }, r, r' \in \{t, f\} \\ {[} \, d' \rightarrow {[} \, d_{i,r'} \,]_{\#} ]_{\langle i,\exists ,r,r'\rangle } \, \text{ for } \, 1 \le i \le n, i \text{ odd }, r, r' \in \{t, f\} \\ (d_{\langle i,r'\rangle }, out) \in \mathcal {R}_{\#} \, \text{ for } \, 1 \le i \le n, i \text{ odd }, r, r' \in \{t, f\} \\ (d_{\langle i,r'\rangle }, out) \in \mathcal {R}_{\langle i, \exists , r, r'\rangle } \, \text{ for } \, 1 \le i \le n, i \text{ odd }, r, r' \in \{t, f\} \end{array} \right. \)

      \(\left. \begin{array}{l} (d'', in) \in \mathcal {R}_{\langle i,\forall ,r,r'\rangle } \, \text{ for } \, 1 \le i \le n, i \text{ even }, r, r' \in \{t, f\} \\ {[} \, d'' \rightarrow {[} \, d'_{r} \,]_{\#} ]_{\langle i,\forall ,r,r'\rangle } \, \text{ for } \, 1 \le i \le n, i \text{ even }, r, r' \in \{t, f\} \\ (d'_{r}, out) \in \mathcal {R}_{\#} \, \text{ for } \, 1 \le i \le n, r, r' \in \{t, f\} \\ (d'_{r}, out) \in \mathcal {R}_{\langle i,\forall ,r,r'\rangle } \, \text{ for } \, 1 \le i \le n-1, r, r' \in \{t, f\} \\ (d'_{r''}, in) \in \mathcal {R}_{\langle i,\forall ,r,r'\rangle } \, \text{ for } \, 1 \le i \le n, i \text{ even }, r, r', r'' \in \{t, f\}, r \ne r'' \\ {[} \, d'_{r''} \rightarrow {[} \, d_{i,r'} \,]_{\#} ]_{\langle i,\forall ,r,r'\rangle } \, \text{ for } \, 1 \le i \le n, i \text{ even }, r, r', r'' \in \{t, f\}, r \ne r'' \\ (d_{i,r'}, out) \in \mathcal {R}_{\#} \, \text{ for } 1 \le i \le n, r, r' \in \{t, f\} \\ \end{array} \right. \)

      \(\left. \begin{array}{l} (d_{i,r'}, out) \in \mathcal {R}_{\langle i,Q,r,r'\rangle } \, \text{ for } \, 1 \le i \le n-1, r, r' \in \{t, f\}, Q \in \{\exists , \forall \} \\ {[} \, d_{1,r} \rightarrow [\quad ]_{yes} \, ]_{skin} \, \text{ for } \, r \in \{t, f\} \end{array} \right. \)

  7. 7.

    \(i_{in} = skin\).

  8. 8.

    \(i_{out} = env\).

4.1 An overview of the computation

The proposed solution follows a brute force scheme of recognizer P systems with symport/antiport rules and membrane creation without environment, and it consists of the following stages:

4.1.1 Generation and first checking stage

By applying rules from 6.4, a membrane structure is generated. In some sense, it reminds a binary tree, but having some “garbage” membranes, labeled by \(\#\), used to generate the objects \(z_{i+1,t}\) and \(z_{i+1,f}\). Besides, using rules from 6.5, objects from \(cod(\varphi )\) will be passed throughout the membrane structure in such a way that in the level i, the i-th variable will be checked and, if the corresponding truth assignment makes true a literal in a clause j, then objects \(c_{i,j,t}\) and \(c_{i,j,f}\) will appear, that will be passed by the membranes up to a membrane labeled by \(\langle n, r\rangle \). This stage takes \(2n^{2} \cdot 2p\) steps.

4.1.2 Second checking stage

Rules from 6.6 are in charge of checking whether all the clauses are satisfied in a truth assignment. For that, if there exists an object \(c_{n,j,r}\) in a membrane labeled by \(\langle n, r\rangle \), it means that the corresponding truth assignment makes true the clause j. Therefore, a membrane labeled by j is created within such a membrane \(\langle n, r\rangle \). Object \(d_{0}\) will go through all membranes, creating a “garbage” membrane within them and passing to the next one, possibly arriving to membrane p. In that case, object \(d_{p}\) creates a new garbage membrane with an object \(d_{n,r}\), that will be useful in the next stage. This stage takes \(3p+5\) steps.

4.1.3 Quantifier checking stage

If an object \(d_{i,r}\) (\(r \in \{t, f\}\)) appears in a membrane, then the quantifier in this level is checked. Depending on the parity of the level, either a universal or an existential quantifier should be checked. In the generation stage, objects \(d'\) and \(d''\) were created for this purpose. On the one hand, when an existential quantifier is being checked, an object \(d'\) will exist in such a membrane, and will change into an object \(d_{i-1,r}\) if and only if there is at least one object \(d_{i,r}\) that has created a membrane \(\langle i,\exists ,r,r'\rangle \). On the other hand, when a universal quantifier is to be checked, an object \(d''\) will be present in such a membrane, and will change into an object \(d_{i-1,r}\) if and only if there are two objects \(d_{i,r}\) that have created two membranes labeled by \(\langle i,\forall ,r,r'\rangle \). These objects will reach the skin membrane giving way to the last stage. This whole stage is computed by the application of rules from 6.6. This stage takes \(8n-6\) steps if n is even and 8n steps if n is odd.

4.1.4 Output stage

Counters \(\alpha \) and \(\alpha '\) are used in this stage to know if an object \(d_{1,r}\) has reached the skin membrane. In such a case, a membrane labeled by yes will be created, and when object \(\alpha _{n^{2}+5n+2p+3}\) reaches the skin membrane, it will go into membrane yes and will change into an object \(\mathtt {yes}\) that will be sent to the environment. In the case that object \(d_{1,r}\) does not appear in the skin membrane, object \(\alpha '_{n^{2}+5n+2p+4}\) will generate a membrane labeled by no, that will make the counter \(\alpha _{n^{2}+5n+2p+3}\) change into an object \(\mathtt {no}\), and will be sent to the environment. Rules from 6.2 and 6.3 are the responsible in this stage. It takes \(p+8\) steps if n is even and \(p+9\) steps if n is odd.

4.2 Results

Next, we prove that \({{\varvec{\Pi }}}\) provides a polynomial time and uniform solution to \(\mathtt {QSAT}\).

Theorem 1

\({\texttt {QSAT}} \in {{\textbf {PMC}}}_{{\widehat{\mathcal {C}\mathcal {C}\mathcal {C}}}(1)}\).

The family of P systems \({{\varvec{\Pi }}}\) is polynomially uniform by Turing machines, polynomially bounded, sound and complete with regard to \((\mathtt {QSAT}, cod, s)\) and both cod and s are polynomial-time computable functions.

Corollary 2

\({\textbf {PSPACE}} \subseteq {\textbf {PMC}}_{{\widehat{\mathcal {C}\mathcal {C}\mathcal {C}}}(1)}\).

Proof

It suffices to know that \(\mathtt {QSAT}\) is a PSPACE-complete problem, \(\mathtt {QSAT} \in {\textbf {PMC}}_{\widehat{\mathcal {C}\mathcal {C}\mathcal {C}}(1)}\) and the class \({\textbf {PMC}}_{\widehat{\mathcal {C}\mathcal {C}\mathcal {C}}(1)}\) is closed under polynomial-time reduction and under complementary. \(\square \)

In [20], a Python simulator developed for this framework can be found. This framework can simulate any P system with symport/antiport rules and creation rules. However, some specific functions have been implemented to make it easier to obtain solution to QSAT formulas. In the main.py file, you can find the line

$$\begin{aligned} \mathtt {formula = examples.generate\_random\_formula(n, p)}. \end{aligned}$$

This line indicates which formula is going to be solved, in this case, a randomly generated formula with at most n variables and p clauses. In the case that an specific formula is to be solved, this line can be changed by, for instance,

$$\begin{aligned} \mathtt {formula = examples.example1())}. \end{aligned}$$

In the file examples.py, it can be found how these formulas are generated, and they can be taken as a reference for creating new formulas. To create a new formula, the same protocol can be followed: we can create a tuple of tuples, where each of these tuples symbolize a clause, and each element of these tuples represent a literal, either in positive form with \(\mathtt {x[i]}\) or in negative form with \(\mathtt {xb[i]}\), where \(\mathtt {i}\) is the variable being used. Therefore, following the format of the examples, the formula

$$\begin{aligned} \varphi \equiv \exists x_{1} \forall x_{2} \exists x_{3} (x_{1} \vee \lnot x_{2}) \wedge (\lnot x_{1} \vee \lnot x_{2} \vee x_{3}) \wedge (x_{2} \vee \lnot x_{3}) \end{aligned}$$

could be represented by

$$\begin{aligned} \mathtt {formula = (('x[1]', 'xb[2]'), ('xb[1]', 'xb[2]', 'x[3]'), ('x[2]', 'xb[3]'))}. \end{aligned}$$

It can be directly simulated by \(\mathtt {python\ main.py}\), and the result will be directly shown in the screen since the compute function will show the contents of the environment.

5 Conclusions and future work

In this work, a result concerning evolutional symport/antiport rules has been improved, in the sense that no evolution is needed in these kinds of rules while using creation rules. While in the previous work, a solution based on a family of P systems from \(\widehat{\mathcal {CCEC}}(1,1)\) was detailed, in this work, we restrict the number of objects used in a symport/antiport rule to one; that is, to P systems from \(\widehat{\mathcal {C}\mathcal {C}\mathcal {C}(1)}\). This is a demonstration of the power of creation rules, showing that rules with a minimal number of objects in symport/antiport rules is enough to reach presumed efficiency. The use of division rules and separation rules with this length of symport/antiport rules gives P systems the power to efficiently solve only problems from P.

From the beginning, creation rules have been only used in cell P systems, because of the biological inspiration of the use of parts of a membrane to create a new membrane within it, but using creation rules in tissue P systems, where new cells would be created in the environment, and not in the cell itself, would be an interesting research line. In this case, the implementation and use of a simulator has helped to correct some errors in the design, showing the advantages of using them as research assistants. The non-evolutive nature of symport/antiport rules are an improvement with respect to their evolutional counterparts, since in the simulator, no changes of these objects must be taken into account, then the same objects will be moved throughout the whole system, except for the ones created when using creation rules.