The scrap-is-not-scrap (sins) experiment began out of a public school education in biology and dissatisfaction with genetic algorithms with their ability to do work.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

119 lines
3.3 KiB

#! /usr/bin/env python3
from argparse import ArgumentParser
from datetime import datetime
from multiprocessing import Process, Queue
from pathlib import Path
from queue import Empty
from sqlalchemy import exists, desc
from tempfile import TemporaryDirectory
import logging
from .mutation import generation, flip, seed_shell
from .orm import db_config, ScrapNode
def sins():
now = '{0:%Y%m%dT%H%M%S}'.format(datetime.utcnow())
parser = ArgumentParser(
description='position independent code (PIC) mutation experiment.')
parser.add_argument('-v', '--verbose', action='count')
parser.add_argument('-s', '--seed', help='path to PIC image.')
parser.add_argument('-o', '--output', help='path to results directory.')
parser.add_argument('-l', '--lineage', default=10,
help='max count of unsuccessful generation.')
args = parser.parse_args()
log_level = logging.INFO
log_format = logging.Formatter('%(message)s')
if args.verbose:
log_level = logging.DEBUG
log_format = logging.Formatter(
'%(levelname)s %(filename)s:%(lineno)d\n%(message)s\n')
logger = logging.getLogger('sins')
logger.setLevel(log_level)
stream_handler = logging.StreamHandler()
stream_handler.setLevel(log_level)
stream_handler.setFormatter(log_format)
logger.addHandler(stream_handler)
if args.output:
log_path = f'{args.output}/sins-{now}.log'
file_handler = logging.FileHandler(log_path)
file_handler.setLevel(log_level)
file_handler.setFormatter(log_format)
logger.addHandler(file_handler)
logger.info(now)
seed_data = seed_shell
if args.seed:
seed = Path(args.seed)
with seed.open('rb') as seed_file:
seed_data = seed_file.read()
seed = ScrapNode(child=seed_data)
logger.debug(f'seed:\n{seed}')
if args.output:
db_path = Path(f'{args.output}/sins.sqlite')
else:
temp_dir = TemporaryDirectory()
db_path = Path(f'{temp_dir.name}/sins.sqlite')
session = db_config(db_path)
logger.info(f'db_path: {db_path}')
if args.seed:
exists = session.query(ScrapNode).filter(
ScrapNode.checksum == seed.checksum)
if exists:
seed = exists[0]
else:
session.add(seed)
session.commit()
else:
recent = session.query(ScrapNode).order_by(desc('ctime')).first()
if recent:
logger.debug(f'recent:\n{recent}')
seed = recent
parent = seed
queue = Queue()
while True:
lineage = 0
scrap = flip(parent.image)
while lineage < args.lineage:
logger.debug(f'lineage: {lineage}')
result = None
proc = Process(target=generation, args=(queue, scrap))
proc.start()
try:
result = queue.get(timeout=1)
except Empty:
lineage += 1
continue
if not result:
lineage += 1
continue
parent = ScrapNode(child=scrap, parent_id=parent.id)
parent.length = result
session.add(parent)
session.commit()
logger.info(f'scrap:\n{parent}')
lineage = 0
scrap = flip(parent.image)