Example #1
0
def printCRN(crn, reversible=True, rates=True):
    """Pretty printing of CRNs.

  Args:
    crn (list of lists): A CRN in list of list format.
    reversible (bool, optional): True to combine reversible reactions into one
      line.  False to split reversible reactions into irreversible reactions.

  Note:
    Order of reactants/products may differ from the order in the crn argument.
  """
    if not rates:
        pcrn = map(lambda rxn: rxn[:2] + [[None]], crn)
    else:
        pcrn = [r for r in crn]

    if reversible:
        pcrn = combine_reversible_reactions(pcrn)
    else:
        pcrn = split_reversible_reactions(pcrn)

    for rxn in pcrn:
        assert len(rxn) == 3
        if len(rxn[2]) == 2:
            print ' + '.join(rxn[0]), '<=>', ' + '.join(rxn[1])
        else:
            print ' + '.join(rxn[0]), '->', ' + '.join(rxn[1])
Example #2
0
 def _parse_crn_file(self, filename):
     # Load data from filename into the proper bisimulation format
     if not os.path.isfile(filename):
         raise Exception(
             "File for unittest is missing: {}".format(filename))
     crn, formal, _, _ = parse_crn_file(filename)
     crn = split_reversible_reactions(crn)
     return ([[Counter(part) for part in rxn] for rxn in crn], formal)
Example #3
0
    def test_example_02(self):
        # """A simple example of finding a bisimulation from group meeting."""

        fcrn = "A + B -> C + D ; A + C -> B + D"
        icrn = "x1 -> x2 ; x3 + x4 <=> x5 ; x2 -> x6 + x8 ; x5 -> x7 ; " + \
               "x3 <=> x6 ; x9 <=> x10 ; x10 + x4 <=> x1 ; x7 -> x9 + x8"

        (fcrn, fs, _) = parse_crn_string(fcrn)
        fcrn = split_reversible_reactions(fcrn)
        fcrn = [[Counter(part) for part in rxn] for rxn in fcrn]

        (icrn, _, _) = parse_crn_string(icrn)
        icrn = split_reversible_reactions(icrn)
        icrn = [[Counter(part) for part in rxn] for rxn in icrn]

        v, _ = bisimulation.test(fcrn, icrn, fs)
        self.assertTrue(v)

        # Test wrong partial interpretation
        partial = dict()
        partial['x2'] = Counter(['B', 'D'])
        partial['x3'] = Counter(['C'])

        v, i = bisimulation.test(fcrn,
                                 icrn,
                                 fs,
                                 interpretation=partial,
                                 permissive='loop-search',
                                 verbose=False)
        self.assertFalse(v)

        del partial['x3']

        v, _ = bisimulation.test(fcrn,
                                 icrn,
                                 fs,
                                 permissive='loop-search',
                                 interpretation=partial,
                                 verbose=False)
        self.assertTrue(v)
Example #4
0
 def _parse_crn_string(self, string):
     crn, formal, _, _ = parse_crn_string(string)
     crn = split_reversible_reactions(crn)
     return ([[Counter(part) for part in rxn] for rxn in crn], formal)
Example #5
0
    def test_example_03(self):
        #""" a follow-up on testing the groupmeeting example """

        fcrn = "A + B -> C + D ; A + C -> B + D"
        icrn = "x1 -> x2 ; x3 + x4 <=> x5 ; x2 -> x6 + x8 ; x5 -> x7 ; " + \
               "x3 <=> x6 ; x9 <=> x10 ; x10 + x4 <=> x1 ; x7 -> x9 + x8"

        # First correct interpretation
        inter1 = {
            'x1': Counter({
                'A': 1,
                'B': 1
            }),
            'x2': Counter({
                'C': 1,
                'D': 1
            }),
            'x3': Counter({'C': 1}),
            'x4': Counter({'A': 1}),
            'x5': Counter({
                'A': 1,
                'C': 1
            }),
            'x6': Counter({'C': 1}),
            'x7': Counter({
                'B': 1,
                'D': 1
            }),
            'x8': Counter({'D': 1}),
            'x9': Counter({'B': 1}),
            'x10': Counter({'B': 1})
        }
        pinter1 = {'x7': Counter({'B': 1, 'D': 1})}

        # Second correct interpretation
        inter2 = {
            'x1': Counter({
                'A': 1,
                'C': 1
            }),
            'x2': Counter({
                'B': 1,
                'D': 1
            }),
            'x3': Counter({'B': 1}),
            'x4': Counter({'A': 1}),
            'x5': Counter({
                'A': 1,
                'B': 1
            }),
            'x6': Counter({'B': 1}),
            'x7': Counter({
                'C': 1,
                'D': 1
            }),
            'x8': Counter({'D': 1}),
            'x9': Counter({'C': 1}),
            'x10': Counter({'C': 1})
        }
        pinter2 = {'x7': Counter({'C': 1, 'D': 1})}

        # CRN preprocessing
        (fcrn, fs, _) = parse_crn_string(fcrn)
        fcrn = split_reversible_reactions(fcrn)
        fcrn = [[Counter(part) for part in rxn] for rxn in fcrn]

        (icrn, _, _) = parse_crn_string(icrn)
        icrn = split_reversible_reactions(icrn)
        icrn = [[Counter(part) for part in rxn] for rxn in icrn]

        # NOTE: Correct behavior
        v, i1 = bisimulation.test(fcrn,
                                  icrn,
                                  fs,
                                  interpretation=pinter1,
                                  permissive='whole-graph')
        self.assertTrue(v)
        self.assertDictEqual(inter1, i1)

        v, i1 = bisimulation.test(fcrn,
                                  icrn,
                                  fs,
                                  interpretation=pinter1,
                                  permissive='loop-search')
        self.assertTrue(v)
        self.assertDictEqual(inter1, i1)

        v, i1 = bisimulation.test(fcrn,
                                  icrn,
                                  fs,
                                  interpretation=pinter1,
                                  permissive='depth-first')
        self.assertTrue(v)
        self.assertDictEqual(inter1, i1)

        v, i1 = bisimulation.test(fcrn,
                                  icrn,
                                  fs,
                                  interpretation=inter1,
                                  permissive='loop-search')
        self.assertTrue(v)
        self.assertDictEqual(inter1, i1)

        v, i1 = bisimulation.test(fcrn,
                                  icrn,
                                  fs,
                                  interpretation=inter1,
                                  permissive='whole-graph')
        self.assertTrue(v)
        self.assertDictEqual(inter1, i1)

        v, i1 = bisimulation.test(fcrn,
                                  icrn,
                                  fs,
                                  interpretation=inter1,
                                  permissive='depth-first')
        self.assertTrue(v)
        self.assertDictEqual(inter1, i1)

        v, i2 = bisimulation.test(fcrn,
                                  icrn,
                                  fs,
                                  interpretation=pinter2,
                                  permissive='loop-search')
        self.assertTrue(v)
        self.assertDictEqual(inter2, i2)

        v, i2 = bisimulation.test(fcrn,
                                  icrn,
                                  fs,
                                  interpretation=pinter2,
                                  permissive='whole-graph')
        self.assertTrue(v)
        self.assertDictEqual(inter2, i2)

        v, i2 = bisimulation.test(fcrn,
                                  icrn,
                                  fs,
                                  interpretation=pinter2,
                                  permissive='depth-first')
        self.assertTrue(v)
        self.assertDictEqual(inter2, i2)
Example #6
0
            (b1, b2) = b
            basis += b1
            basis_raw += b2
    else:
        b = enumerate_basis(crn, fs)
        if b == None:  # irregular or nontidy
            return None
        #TODO: do I see a bug here? what if !optimize & !inter2?
        (basis, basis_raw) = b
    if inter: return (basis, basis_raw)
    return basis


if __name__ == "__main__":
    import sys
    from nuskell.parser import parse_crn_file, split_reversible_reactions
    crn_file = sys.argv[1]

    # # Add appropriate extensions if necessary.
    # if len(crn_file) < 4 or crn_file[-4:] != ".crn": crn_file += ".crn"

    (crn, formal_species, const_species) = parse_crn_file(crn_file)
    crn = split_reversible_reactions(crn)

    crn = remove_const(crn, const_species)
    basis = find_basis(crn, formal_species)
    if basis != None:
        print "Formal basis :"
        for (r, p) in basis:
            print_reaction([r, p])
Example #7
0
 def test_split_reversible_reactions(self):
   crn = "A+B->X+Y\nA<=>X"
   crn, fs, signals, fuels = parse_crn_string(crn)
   res = [[['A', 'B'], ['X', 'Y'], [None]], [['A'], ['X'], [None]], [['X'], ['A'],[None]]]
   self.assertEqual(split_reversible_reactions(crn), res, 'split irreversible reactions')
Example #8
0
def main():
    """ CRN condensation.
  
  Takes a formal and an implementation CRN and verifies the equivalence
  according to pathway decomposition or bisimulation.

  Throws out edges from the graph to see how equivalence notion changes.

  """
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser = get_nuskell_args(parser)
    args = parser.parse_args()

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # Parse and process input CRN
    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    input_crn = sys.stdin.readlines()
    input_crn = "".join(input_crn)
    crn1, crn1s, _, _ = parse_crn_string(input_crn)

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~
    # Verify equivalence of CRNs
    # ~~~~~~~~~~~~~~~~~~~~~~~~~~
    print "\nVerification preprocessing..."
    crn1 = split_reversible_reactions(crn1)

    if args.verbose:
        print "Formal CRN:"
        printCRN(crn1, reversible=True, rates=False)

    crn2, crn2s, _, _ = parse_crn_file(args.compare)
    crn2 = split_reversible_reactions(crn2)

    if args.verbose:
        print "Implementation CRN:"
        printCRN(crn2, reversible=True, rates=False)

    interpret = dict()
    if not args.independent:
        print 'Ad-hoc partial interpretation:'
        formals = set(crn1s)
        for sp in crn2s:
            if sp in formals:
                interpret[sp] = Counter([sp])

        if interpret and args.verbose:
            for impl, formal in sorted(interpret.items()):
                print "  {} => {}".format(
                    impl, ', '.join([x for x in formal.elements()]))

    print "\nVerification using:", args.verify
    for meth in args.verify:
        v, i = verify(crn1,
                      crn2,
                      crn1s,
                      method=meth,
                      interpret=interpret,
                      verbose=(args.verbose > 1),
                      timeout=args.verify_timeout)

        if i and args.verbose:
            if not v: i = i[0]
            print "Returned interpretation ['{}']:".format(meth)
            for impl, formal in sorted(i.items()):
                print "  {} => {}".format(
                    impl, ', '.join([x for x in formal.elements()]))

        if v is True:
            print " {}: CRNs are {} equivalent.".format(v, meth)
        elif v is False:
            print " {}: CRNs are not {} equivalent.".format(v, meth)
        elif v is None:
            print " {}: {} verification did not terminate within {} seconds.".format(
                v, meth, args.verify_timeout)
Example #9
0
 def _parse_crn_string(self, string):
     crn, formal, _, _ = parse_crn_string(string)
     crn = split_reversible_reactions(crn)
     return (crn, formal)