Esempio n. 1
0
def verify(dnn: OperationGraph, phi: Expression):
    logger = logging.getLogger(__name__)
    dnn = dnn.simplify()
    phi.networks[0].concretize(dnn)

    result = UNSAT
    property_extractor = ConvexPolytopeExtractor()
    with tempfile.TemporaryDirectory() as dirname:
        for prop in property_extractor.extract_from(phi):
            layers = prop.output_constraint.as_layers(
                prop.network, translator_error=ReluplexTranslatorError
            )
            input_interval = prop.input_constraint.as_hyperrectangle()
            nnet_file_name = to_nnet_file(
                input_interval,
                layers,
                dirname=dirname,
                translator_error=ReluplexTranslatorError,
            )
            logger.debug("Running reluplex")
            executor = CommandLineExecutor(
                "reluplex", f"{nnet_file_name}", verifier_error=ReluplexError
            )
            out, err = executor.run()
            logger.debug("Parsing results")
            result |= parse_results(out, err)
            if result == SAT:
                logger.debug("SAT! Validating counter example.")
                validate_counter_example(prop, out, err)
            if result == SAT or result == UNKNOWN:
                return result

    return result
Esempio n. 2
0
def verify(dnn: OperationGraph, phi: Expression, **kwargs: Dict[str, Any]):
    logger = logging.getLogger(__name__)
    dnn = dnn.simplify()
    phi.networks[0].concretize(dnn)

    result = UNSAT
    property_extractor = ConvexPolytopeExtractor()
    with tempfile.TemporaryDirectory() as dirname:
        for prop in property_extractor.extract_from(phi):
            layers = prop.output_constraint.as_layers(
                prop.network,
                extra_layer_types=MIPVERIFY_LAYER_TYPES,
                translator_error=MIPVerifyTranslatorError,
            )
            input_interval = prop.input_constraint.as_hyperrectangle()
            mipverify_inputs = to_mipverify_inputs(
                input_interval,
                layers,
                dirname=dirname,
                translator_error=MIPVerifyTranslatorError,
            )
            logger.debug("Running mipverify")
            executor = CommandLineExecutor(
                "julia",
                mipverify_inputs["property_path"],
                verifier_error=MIPVerifyError,
            )
            out, err = executor.run()
            logger.debug("Parsing results")
            result |= parse_results(out, err)
            if result == SAT or result == UNKNOWN:
                return result

    return result
Esempio n. 3
0
 def extract_from(self, expression: Expression) -> Iterable[Property]:
     logger = logging.getLogger(__name__)
     self.existential = False
     if isinstance(expression, Exists):
         raise NotImplementedError()  # TODO
         expression = ~expression
         self.existential = True
     expression = expression.canonical()
     not_expression = Or(~expression)
     for conjunction in not_expression:
         logger.info("CONJUNCTION: %s", conjunction)
         if len(conjunction.networks) != 1:
             continue
             raise self.translator_error(
                 "Exactly one network input and output are required")
         if len(conjunction.variables) != 1:
             raise self.translator_error(
                 "Exactly one network input is required")
         for prop in super().extract_from(conjunction):
             if prop.input_constraint.as_hyperrectangle(
             ).is_consistent == False:
                 continue
             if prop.output_constraint.is_consistent == False:
                 continue
             yield prop
Esempio n. 4
0
def verify(dnn: OperationGraph,
           phi: Expression,
           domain="deeppoly",
           timeout_lp=1.0,
           timeout_milp=1.0,
           use_area_heuristic=True,
           **kwargs: Dict[str, Any]):
    logger = logging.getLogger(__name__)
    dnn = dnn.simplify()
    phi.networks[0].concretize(dnn)

    result = UNSAT
    property_extractor = HalfspacePolytopePropertyExtractor(
        HyperRectangle, HalfspacePolytope)
    for prop in property_extractor.extract_from(~phi):
        if prop.input_constraint.num_variables > 1:
            raise ERANTranslatorError(
                "Unsupported network: More than 1 input variable")
        with tf.Session(graph=tf.Graph()) as tf_session:
            layers = as_layers(
                prop.suffixed_op_graph(),
                extra_layer_types=ERAN_LAYER_TYPES,
                translator_error=ERANTranslatorError,
            )
            input_interval = prop.input_constraint

            spec_lb = input_interval.lower_bounds[0]
            spec_ub = input_interval.upper_bounds[0]
            if len(spec_lb.shape) == 4:
                spec_lb = spec_lb.transpose((0, 2, 3, 1))
                spec_ub = spec_ub.transpose((0, 2, 3, 1))
            tf_graph = as_tf(layers, translator_error=ERANTranslatorError)
            eran_model = ERAN(tf_graph, session=tf_session)
            _, nn, nlb, nub = eran_model.analyze_box(spec_lb.flatten().copy(),
                                                     spec_ub.flatten().copy(),
                                                     domain, timeout_lp,
                                                     timeout_milp,
                                                     use_area_heuristic,
                                                     **kwargs)
            output_lower_bound = np.asarray(nlb[-1])
            output_upper_bound = np.asarray(nub[-1])
            logger.debug("output lower bound: %s", output_lower_bound)
            logger.debug("output upper bound: %s", output_upper_bound)
            result |= check(output_lower_bound, output_upper_bound)
        if result == SAT or result == UNKNOWN:
            return result

    return result
Esempio n. 5
0
def verify(dnn: OperationGraph, phi: Expression, **kwargs: Dict[str, Any]):
    logger = logging.getLogger(__name__)
    dnn = dnn.simplify()
    phi.networks[0].concretize(dnn)

    result = UNSAT
    property_extractor = HalfspacePolytopePropertyExtractor(
        HyperRectangle, HalfspacePolytope)
    with tempfile.TemporaryDirectory() as dirname:
        for prop in property_extractor.extract_from(~phi):
            if prop.input_constraint.num_variables > 1:
                raise NeurifyTranslatorError(
                    "Unsupported network: More than 1 input variable")
            layers = as_layers(
                prop.suffixed_op_graph(),
                translator_error=NeurifyTranslatorError,
            )
            neurify_inputs = to_neurify_inputs(
                prop.input_constraint,
                layers,
                dirname=dirname,
                translator_error=NeurifyTranslatorError,
            )
            logger.debug("Running neurify")
            executor = CommandLineExecutor(
                "neurify",
                "-n",
                neurify_inputs["nnet_path"],
                "-x",
                neurify_inputs["input_path"],
                "-sl",
                "0.0000000000001",  # TODO: remove magic number
                "-I",
                neurify_inputs["input_interval_path"],
                "-v",
                *[f"--{k}={v}" for k, v in kwargs.items() if v is not None],
                verifier_error=NeurifyError,
            )
            out, err = executor.run()
            logger.debug("Parsing results")
            result |= parse_results(out, err)
            if result == SAT:
                logger.debug("SAT! Validating counter example.")
                validate_counter_example(prop, out, err)
            if result == SAT or result == UNKNOWN:
                return result

    return result
Esempio n. 6
0
    def run(self):
        logger = logging.getLogger(__name__)
        arg_string = " ".join(self.args)
        logger.info(f"EXECUTING: {arg_string}")
        proc = None
        try:
            proc = sp.Popen(self.args,
                            stdout=sp.PIPE,
                            stderr=sp.PIPE,
                            encoding="utf8")

            self.output_lines = []
            self.error_lines = []
            while proc.poll() is None:
                for (name, stream, lines) in [
                    ("STDOUT", proc.stdout, self.output_lines),
                    ("STDERR", proc.stderr, self.error_lines),
                ]:
                    ready, _, _ = select.select([stream], [], [], 0)
                    if not ready:
                        continue
                    line = stream.readline()
                    if not line:
                        continue
                    line = line.strip()
                    lines.append(line)
                    logger.debug(f"[{name}]:{line}")
            for line in proc.stdout.readlines():
                line = line.strip()
                logger.debug(f"[STDOUT]:{line}")
                self.output_lines.append(line)
            for line in proc.stderr.readlines():
                line = line.strip()
                logger.debug(f"[STDERR]:{line}")
                self.error_lines.append(line)
            if proc.returncode != 0:
                raise self.verifier_error(f"Return code: {proc.returncode}")
        finally:
            if proc is not None:
                proc.stderr.close()
                proc.stdout.close()

        return self.output_lines, self.error_lines
Esempio n. 7
0
def verify(dnn: OperationGraph, phi: Expression, **kwargs: Dict[str, Any]):
    logger = logging.getLogger(__name__)
    dnn = dnn.simplify()
    phi.networks[0].concretize(dnn)

    result = UNSAT
    property_extractor = ConvexPolytopeExtractor()
    with tempfile.TemporaryDirectory() as dirname:
        for prop in property_extractor.extract_from(phi):
            layers = prop.output_constraint.as_layers(
                prop.network, translator_error=NeurifyTranslatorError)
            input_interval = prop.input_constraint.as_hyperrectangle()
            neurify_inputs = to_neurify_inputs(
                input_interval,
                layers,
                dirname=dirname,
                translator_error=NeurifyTranslatorError,
            )
            epsilon = neurify_inputs["epsilon"]
            logger.debug("Running neurify")
            executor = CommandLineExecutor(
                "neurify",
                "-n",
                neurify_inputs["nnet_path"],
                "-x",
                neurify_inputs["input_path"],
                "-sl",
                "0.000000000001",  # TODO: remove magic number
                f"--linf={epsilon}",
                "-v",
                *[f"--{k}={v}" for k, v in kwargs.items() if v is not None],
                verifier_error=NeurifyError,
            )
            out, err = executor.run()
            logger.debug("Parsing results")
            result |= parse_results(out, err)
            if result == SAT:
                logger.debug("SAT! Validating counter example.")
                validate_counter_example(prop, out, err)
            if result == SAT or result == UNKNOWN:
                return result

    return result
Esempio n. 8
0
    def run(self):
        logger = logging.getLogger(__name__)
        arg_string = " ".join(self.args)
        logger.info(f"EXECUTING: {arg_string}")
        try:
            proc = sp.Popen(self.args, stdout=sp.PIPE, stderr=sp.PIPE, encoding="utf8")

            self.output_lines = []
            self.error_lines = []
            while proc.poll() is None:
                readables, _, _ = select.select([proc.stdout, proc.stderr], [], [], 0)
                while len(readables) > 0:
                    io = readables.pop()
                    line = io.readline().strip()
                    if not line:
                        continue
                    prefix = ""
                    if io.fileno() == proc.stdout.fileno():
                        self.output_lines.append(line)
                        prefix = "[STDOUT]:"
                    elif io.fileno() == proc.stderr.fileno():
                        self.error_lines.append(line)
                        prefix = "[STDERR]:"
                    logger.debug(f"{prefix}{line}")
            if proc.returncode != 0:
                raise self.verifier_error(f"Received signal: {-proc.returncode}")

            for line in proc.stderr.readlines():
                line = line.strip()
                if line:
                    logger.debug(f"[STDERR]:{line}")
                    self.error_lines.append(line)
            for line in proc.stdout.readlines():
                line = line.strip()
                if line:
                    logger.debug(f"[STDOUT]:{line}")
                    self.output_lines.append(line)
        finally:
            proc.stderr.close()
            proc.stdout.close()

        return self.output_lines, self.error_lines
Esempio n. 9
0
def verify(dnn: OperationGraph, phi: Expression, **kwargs: Dict[str, Any]):
    logger = logging.getLogger(__name__)
    dnn = dnn.simplify()
    phi.networks[0].concretize(dnn)

    result = UNSAT
    property_extractor = HalfspacePolytopePropertyExtractor(
        HyperRectangle, HalfspacePolytope)
    with tempfile.TemporaryDirectory() as dirname:
        for prop in property_extractor.extract_from(~phi):
            if prop.input_constraint.num_variables > 1:
                raise MIPVerifyTranslatorError(
                    "Unsupported network: More than 1 input variable")
            layers = as_layers(
                prop.suffixed_op_graph(),
                extra_layer_types=MIPVERIFY_LAYER_TYPES,
                translator_error=MIPVerifyTranslatorError,
            )
            mipverify_inputs = to_mipverify_inputs(
                prop.input_constraint,
                layers,
                dirname=dirname,
                translator_error=MIPVerifyTranslatorError,
            )
            logger.debug("Running mipverify")
            executor = CommandLineExecutor(
                "julia",
                mipverify_inputs["property_path"],
                verifier_error=MIPVerifyError,
            )
            out, err = executor.run()
            logger.debug("Parsing results")
            result |= parse_results(out, err)
            if result == SAT or result == UNKNOWN:
                return result

    return result