Exemple #1
0
def test_synthesizer_count_5s():
    libSynth = getLib()

    tr1_1_28_28 = mkRealTensorSort([1, 1, 28, 28])
    tr1_1 = mkRealTensorSort([1, 1])
    tb1_1 = mkBoolTensorSort([1, 1])

    libSynth.addItems([
        PPLibItem('recog_5', func(tr1_1_28_28, tb1_1), None),
    ])

    fn_sort = func(lst(tr1_1_28_28), tr1_1)

    synth = SymbolicSynthesizer(libSynth, fn_sort)

    I = 10000
    i = 0
    for prog, unkMap in synth.genProgs():

        i = i + 1
        if i > I:
            break
        if i % 100 == 0:
            print(i)

        unks = ASTUtils.getUnks(prog)

        if len(unks) > 1:
            continue

        for unk in unks:
            if ASTUtils.isAbstract(unk.sort):
                continue

        print(repr_py_ann(prog))
Exemple #2
0
def renameSortVars(libItemSort, term):
    i = 0
    svs = ASTUtils.getSortVars(libItemSort)
    for sv in svs:
        newsv = getSortVarNotInTerm(sv, term)
        libItemSort = ASTUtils.replaceAllSubTerms(libItemSort, sv, newsv)

    return libItemSort
Exemple #3
0
def renameDimVars(libItemSort, term):
    i = 0
    dvs = ASTUtils.getDimVars(libItemSort)
    for dv in dvs:
        newdv = mkDimVarNotInTerm(dv, term)
        libItemSort = ASTUtils.replaceAllSubTerms(libItemSort, dv, newdv)

    return libItemSort
Exemple #4
0
def substOne(a: PPSortOrDimVar, b: PPSortOrDim, sortTerm: PPSort) -> PPSort:
    """
    substitute b for all the occurrences of variable a in sortTerm
    """
    term1 = ASTUtils.applyTd(sortTerm, lambda x: type(x) == PPSortVar,
                             lambda x: b if x == a else x)
    term2 = ASTUtils.applyTd(term1, lambda x: type(x) == PPDimVar, lambda x: b
                             if x == a else x)
    return term2
    def getProgsAndUnkSortWithUniqueNames(self, progs):
        res = []
        for prog in progs:
            assert (not ASTUtils.isOpen(prog))

            unkSortMap = {}
            if ASTUtils.hasUnk(prog):
                prog = self._giveUniqueNamesToUnks(prog)
                unkSortMap = ASTUtils.getUnkNameSortMap(prog)

            res.append((prog, unkSortMap))

        return res
Exemple #6
0
def expandToUnk(term: PPTerm, ntId: int) -> Optional[PPTerm]:
    """
    Generate a new term by replacing a "ntId"th NT from a "term" with a PPTermUnk
    """
    nt = ASTUtils.getNthNT(term, ntId)

    # Avoid generating Unk of type PPDimConst, PPDimVar, PPEumSort, or PPInt()
    if isinstance(nt.sort, PPDimConst) or isinstance(nt.sort, PPDimVar) or isinstance(nt.sort, PPEnumSort) or \
            isinstance(nt.sort, PPInt):
        return None

    unk = ASTDSL.mkUnk(nt.sort)

    # subst = unifyOne(unk.sort, nt.sort)
    #
    # if subst != []:
    #     print("non empty subst")
    #
    # termExpanded = None
    # if subst is not None:
    #     termUnified = applySubst(subst, term)
    #     termExpanded = ReprUtils.replaceNthNT(termUnified, ntId, unk)

    termNew = ReprUtils.replaceNthNT(term, ntId, unk)
    return termNew
Exemple #7
0
def testProgTreeSize():
    lib = mkDefaultLib()

    # region #+ Add recogFive to library
    inType = mkRealTensorSort([1, 1, 28, 28])
    outType = mkBoolTensorSort([1, 1])
    recogDigitType = mkFuncSort(inType, outType)

    lib.addItem(PPLibItem('recogFive', recogDigitType, None))
    # endregion

    inType = mkListSort(mkRealTensorSort([1, 1, 28, 28]))
    outType = mkRealTensorSort([1, 1])
    sort = mkFuncSort(inType, outType)

    prog = \
        PPFuncApp(fn=PPVar(name='lib.compose'),
                  args=[PPFuncApp(fn=PPVar(name='lib.fold_l'),
                                  args=[PPTermUnk(name='nn_fun_x_906',
                                                  sort=PPFuncSort(
                                                      args=[PPTensorSort(param_sort=PPReal(),
                                                                         shape=[PPDimConst(value=1),
                                                                                PPDimConst(value=1)]),
                                                            PPTensorSort(param_sort=PPBool(),
                                                                         shape=[PPDimConst(value=1),
                                                                                PPDimConst(value=1)])],
                                                      rtpe=PPTensorSort(param_sort=PPReal(),
                                                                        shape=[PPDimConst(value=1),
                                                                               PPDimConst(value=1)]))),
                                        PPFuncApp(fn=PPVar(name='lib.zeros'), args=[PPIntConst(value=1)])]),
                        PPFuncApp(fn=PPVar(name='lib.map_l'), args=[PPVar(name='lib.recogFive')])])

    size = ASTUtils.progTreeSize(prog)

    assert size == 7
Exemple #8
0
def print_progs_e(fn_sort, libSynth, targetSize):
    synth = SymbolicSynthesizer(libSynth, fn_sort)
    cnt = 1
    ecnt = 1
    for prog, unkMap in synth.genProgs():
        sz = ASTUtils.getSize2(prog)
        if sz > targetSize:
            break

        res, code = NeuralSynthesizer.is_evaluable(prog, fn_sort)
        if res:
            if 'lib.compose(lib.repeat(10, lib.conv_g(lib.nn_relax))' in repr_py(
                    prog):
                print('.', cnt, sz, repr_py(prog), ecnt)
            ecnt += 1
        else:
            if 'lib.compose(lib.repeat(10, lib.conv_g(lib.nn_relax))' in repr_py(
                    prog):
                print("#", cnt, sz, repr_py(prog), code)
                test = False
                if test:
                    res, code = NeuralSynthesizer.is_evaluable(prog, fn_sort)
        # print(cnt, sz, prog)
        cnt += 1
    print(cnt)
Exemple #9
0
def expandToFuncApp(lib: FnLibrary, term: PPTerm, ntId: int,
                    fname: str) -> Optional[PPTerm]:
    resTerm = None
    # Not needed now as there are no lambda terms
    # libItem = ScopeUtils.getAVarInScope(lib, term, ntId, fname)
    libItem = lib.getWithLibPrefix(fname)
    assert libItem
    nt = ASTUtils.getNthNT(term, ntId)

    libItem = alphaConvertLibItem(libItem, term)
    # TODO: expandToVar passed nt.sort as second argument
    subst = unifyOne(nt.sort, libItem.sort.rtpe)

    if not gUseTypes:
        if subst is None:
            subst = []

    if subst is not None:
        nts = [PPTermNT('Z', arg_sort) for arg_sort in libItem.sort.args]
        fnApp = PPFuncApp(PPVar(libItem.name), nts)

        termUnified = applySubst(subst, term)
        fnAppUnified = applySubst(subst, fnApp)

        resTerm = ReprUtils.replaceNthNT(termUnified, ntId, fnAppUnified)

    return resTerm
 def getActionsAllNts(self, st: PPTerm) -> List[Action]:
     # This results in duplicate programs.
     numNts = ASTUtils.getNumNTs(st)
     actions = []
     for ntId in range(1, numNts + 1):
         for ruleId in range(Rules.numRules):
             actions.append(Action(ntId, ruleId))
     return actions
    def _giveUniqueNamesToUnks(self, st: PPTerm):
        def rename(nt: PPTermUnk):
            if nt.name == 'Unk':
                return PPTermUnk("nn_fun_%s_%d" % (self.nnprefix, self._ntNameGen()), nt.sort)
            else:  # Renaming not required.
                return nt

        return ASTUtils.applyTd(st, ASTUtils.isUnk, rename)
Exemple #12
0
def getSortVarNotInTerm(sv, term):
    """
    get a sv that is not in term
    """
    i = 0
    while ASTUtils.exists(term, lambda x: x == sv):
        i = i + 1
        newsv = PPSortVar(sv.name + '_' + str(i))
        sv = newsv

    return sv
Exemple #13
0
def mkDimVarNotInTerm(dv, term):
    """
    get a dv that is not in term
    """
    i = 0
    while ASTUtils.exists(term, lambda x: x == dv):
        i = i + 1
        newdv = PPDimVar(dv.name + '_' + str(i))
        dv = newdv

    return dv
Exemple #14
0
def expandDimConst(term: PPTerm, ntId: int) -> Optional[PPTerm]:
    """
    Expand dimension constant to integer constants (Required for fold zeros)
    """
    nt = ASTUtils.getNthNT(term, ntId)
    if type(nt.sort) != PPDimConst:
        return None

    subTerm = PPIntConst(nt.sort.value)
    termExpanded = ReprUtils.replaceNthNT(term, ntId, subTerm)
    return termExpanded
Exemple #15
0
def print_progs(fn_sort, libSynth, targetSize):
    synth = SymbolicSynthesizer(libSynth, fn_sort)
    cnt = 0
    for prog, unkMap in synth.genProgs():
        sz = ASTUtils.getSize2(prog)
        if sz > targetSize:
            break

        cnt += 1
        print(cnt, sz, repr_py(prog))
        # print(cnt, sz, prog)

    print(cnt)
Exemple #16
0
def applyExpandEnum(lib: FnLibrary, term: PPTerm, ntId: int) -> List[PPTerm]:
    res = []

    nt = ASTUtils.getNthNT(term, ntId)
    if type(nt.sort) != PPEnumSort:
        return res

    for i in range(nt.sort.start, nt.sort.end + 1):
        subTerm = PPIntConst(i)
        nxtTerm = expandEnum(term, ntId, subTerm)
        if nxtTerm is not None:
            res.append(nxtTerm)

    return res
Exemple #17
0
def test_synthesizer_sum_digits():
    libSynth = getLib()

    input_type = mkListSort(mkRealTensorSort([1, 1, 28, 28]))
    output_type = mkRealTensorSort([1, 1])
    fn_sort = mkFuncSort(input_type, output_type)

    tr1_1_28_28 = mkRealTensorSort([1, 1, 28, 28])
    tb_1_10 = mkBoolTensorSort([1, 10])
    classify_digit = mkFuncSort(tr1_1_28_28, tb_1_10)

    libSynth.addItems([
        PPLibItem('classify_digit', classify_digit, None),
    ])

    synth = SymbolicSynthesizer(libSynth, fn_sort)

    I = 10000
    i = 0
    for prog, unkMap in synth.genProgs():

        i = i + 1
        if i > I:
            break
        if i % 100 == 0:
            print(i)

        unks = ASTUtils.getUnks(prog)

        if len(unks) > 1:
            continue

        for unk in unks:
            if ASTUtils.isAbstract(unk.sort):
                continue

        print(repr_py_ann(prog))
def _processProg(prog, cmts):
    newProgs = []
    sortVars = ASTUtils.getSortVars(prog)
    if sortVars:
        sortVar = sortVars[0]
        progress = True
        for cmt in cmts:
            newProg = substOne(sortVar, cmt, prog)
            newProgs.append(newProg)
    else:
        # Add the program as it is
        progress = False
        newProgs.append(prog)

    return newProgs, progress
    def genProg(self, sort: PPSort, maxDepth: int) -> Optional[PPTerm]:
        state = PPTermNT('Z', sort)
        di = 0

        while di < maxDepth:
            nxtState = self.getNextRandomSt(state)
            if nxtState is None:
                return None
            elif not ASTUtils.isOpen(nxtState):
                return nxtState
            else:  # isOpen
                state = nxtState
            di += 1

        return None
Exemple #20
0
 def update_library(self, lib: FnLibrary,
                    task_result_single: TaskResultSingle, taskid):
     if self.seq_settings.update_library:
         # Add learned modules to the library
         top_solution = task_result_single.get_top_solution_details()
         if top_solution is not None:
             prog, resDict = top_solution
             unk_sort_map: Dict[str,
                                PPSort] = ASTUtils.getUnkNameSortMap(prog)
             lib_items = [
                 PPLibItem(unk, unk_sort, resDict['new_fns_dict'][unk])
                 for unk, unk_sort in unk_sort_map.items()
             ]
             if lib_items.__len__() > 0:
                 lib.addItems(lib_items)
             # Save the library.
             lib.save1(self.getLibLocation(), taskid)
Exemple #21
0
    def traverse(iterm: PPTerm, ivars: Dict[str, PPVarDecl]):
        nonlocal count, varDecls, found

        if type(iterm) == PPTermNT:
            count += 1
            if count == n:
                varDecls = ivars
                found = True
        elif type(iterm) == PPLambda:
            iVarsNew = ivars.copy()
            for param in iterm.params:
                iVarsNew[param.name] = param

            traverse(iterm.body, iVarsNew)
        else:
            for c in ASTUtils.deconstruct(iterm):
                if found:
                    break
                traverse(c, ivars)
    def genProgs(self) -> Iterable[Tuple[PPTerm, Dict[str, PPSort]]]:
        for prog in self.genTerms():
            if self.isOpen(prog):
                continue

            if self.concreteTypes:
                maxSortVarsToBeInstantiated = 2
                eprogs = instantiateSortVar(prog, self.concreteTypes,
                                            maxSortVarsToBeInstantiated)
            else:
                eprogs = [prog]

            for eprog in eprogs:
                unkSortMap = {}
                if self.hasUnk(eprog):
                    eprog = self._giveUniqueNamesToUnks(eprog)
                    unkSortMap = ASTUtils.getUnkNameSortMap(eprog)

                yield eprog, unkSortMap
Exemple #23
0
def expandToVar(lib: FnLibrary, term: PPTerm, ntId: int,
                vname: str) -> Optional[PPTerm]:
    """
    Generate a new term by replacing a "ntId"th NT from a "term" with a variable (in scope) with name "fname"
    """
    nt = ASTUtils.getNthNT(term, ntId)
    # libItem = ScopeUtils.getAVarInScope(lib, term, ntId, vname)
    libItem = lib.getWithLibPrefix(vname)
    assert libItem

    libItem = alphaConvertLibItem(libItem, term)
    subst = unifyOne(libItem.sort, nt.sort)

    if not gUseTypes:
        if subst is None:
            subst = []

    termExpanded = None
    if subst is not None:
        termUnified = applySubst(subst, term)
        termExpanded = ReprUtils.replaceNthNT(termUnified, ntId,
                                              PPVar(libItem.name))

    return termExpanded
 def isOpen(self, st: PPTerm) -> bool:
     return ASTUtils.isOpen(st)
Exemple #25
0
def is_evaluable(st, ns) -> Tuple[bool, int]:
    # The program should not be open (no non-terminals).
    if ASTUtils.isOpen(st):
        return False, 1

    unks = ASTUtils.getUnks(st)

    # At most 3 unks for now.
    if len(unks) > 3:
        return False, 2

    # return False, 3
    # print(repr_py(st))

    number_of_mlp_nns = 0

    for unk in unks:
        # type variables and dimension variables not allowed.
        if ASTUtils.isAbstract(unk.sort):
            return False, 3

        # Only function types allowed
        if type(unk.sort) != PPFuncSort:
            return False, 4

        # ******* INPUTS ******* :
        # An input to a function can't be a function
        if any([type(arg_sort) == PPFuncSort for arg_sort in unk.sort.args]):
            return False, 11

        fn_input_sort = unk.sort.args[0]
        fn_output_sort = unk.sort.rtpe

        # No more than 2 arguments
        num_input_arguments = unk.sort.args.__len__()
        if num_input_arguments > 1:
            in1_is_2d_tensor = type(
                unk.sort.args[0]
            ) == PPTensorSort and unk.sort.args[0].shape.__len__() == 2
            in2_is_2d_tensor = type(
                unk.sort.args[1]
            ) == PPTensorSort and unk.sort.args[1].shape.__len__() == 2
            out_is_2d_tensor = type(
                unk.sort.rtpe) == PPTensorSort and unk.sort.rtpe.shape.__len__(
                ) == 2
            # If a function takes 2 inputs, they'll be concatenated. Thus, we need them to be 2 dimensional tensors
            if num_input_arguments == 2 and in1_is_2d_tensor and in2_is_2d_tensor and out_is_2d_tensor:
                continue
            else:
                return False, 5

        # If the NN's input is a list, it should be: List<2dTensor> -> 2dTensor
        # (as seq-to-seq models aren't supported)
        # We support List<2dTensor> -> 2dTensor
        if type(unk.sort.args[0]) == PPListSort:
            in_is_list_of_2d_tensors = type(
                unk.sort.args[0].param_sort) == PPTensorSort and len(
                    unk.sort.args[0].param_sort.shape) == 2
            out_is_2d_tensor = type(
                unk.sort.rtpe) == PPTensorSort and unk.sort.rtpe.shape.__len__(
                ) == 2

            if in_is_list_of_2d_tensors and out_is_2d_tensor:
                continue
            else:
                return False, 6

        # If the input to the NN is an image:
        cnn_feature_dim = 64
        input_is_image = type(
            fn_input_sort) == PPTensorSort and fn_input_sort.shape.__len__(
            ) == 4
        if input_is_image:
            # if the input is of size [batch_size, _, 28, 28], the output must be of size [batch_size, 32, 4, 4]
            cond0a1 = fn_input_sort.shape[
                2].value == 28 and fn_input_sort.shape[3].value == 28
            cond0a2 = type(fn_output_sort) == PPTensorSort and fn_output_sort.shape.__len__() == 4 and \
                      fn_output_sort.shape[1].value == cnn_feature_dim \
                      and fn_output_sort.shape[2].value == 4 and fn_output_sort.shape[3].value == 4
            # if the input is of size [batch_size, 32, 4, 4], the output must be two dimensional
            cond0b1 = fn_input_sort.shape[1].value == cnn_feature_dim \
                      and fn_input_sort.shape[2].value == 4 and fn_input_sort.shape[3].value == 4
            cond0b2 = type(
                fn_output_sort
            ) == PPTensorSort and fn_output_sort.shape.__len__() == 2

            if not ((cond0a1 and cond0a2) or (cond0b1 and cond0b2)):
                return False, 50

            if cond0b1 and cond0b2:
                number_of_mlp_nns += 1
            continue

        # if the input is a 2d tensor:
        in_is_2d_tensor = type(
            unk.sort.args[0]
        ) == PPTensorSort and unk.sort.args[0].shape.__len__() == 2
        out_is_2d_tensor = type(
            unk.sort.rtpe) == PPTensorSort and unk.sort.rtpe.shape.__len__(
            ) == 2
        if in_is_2d_tensor:
            if out_is_2d_tensor:
                number_of_mlp_nns += 1
            else:
                return False, 51

        return False, 52

    lib_names = get_lib_names(st)
    # don't allow multiple repeats, as we could just keep on stacking these.
    if lib_names.count("repeat") > 1:
        return False, 15

    # lib_names = self.interpreter
    for lib_name in lib_names:
        # TODO: check if the functions is part of graph convolution, but is used outside of a conv_g operator.

        if type(ns.lib.items[lib_name].obj) == NetMLP:
            number_of_mlp_nns += 1

    # don't allow for multiple MLPs, as we can just keep on stacking them
    # (thus going into architecture search, which is out of scope)
    if number_of_mlp_nns > 1:
        return False, 16

    return True, 0
 def getActionCost(self, st: PPTerm, action: Action) -> float:
     return ASTUtils.getSize(st)
Exemple #27
0
def expandNthNT(term: PPTerm, ntId: int, expand: Callable[[PPTermNT],
                                                          PPTerm]) -> PPTerm:
    newTerm = ASTUtils.applyTdOnce(term, ASTUtils.isNthNT(ntId), expand)
    return newTerm
 def hasUnk(self, st: PPTerm) -> bool:
     return ASTUtils.hasUnk(st)
Exemple #29
0
def replaceNthNT(term: PPTerm, ntId: int, newSubTerm: PPTerm) -> PPTerm:
    newTerm = ASTUtils.applyTdOnce(term, ASTUtils.isNthNT(ntId),
                                   lambda nt: newSubTerm)
    return newTerm
Exemple #30
0
def expandEnum(term: PPTerm, ntId: int, subTerm: PPTerm) -> Optional[PPTerm]:
    nt = ASTUtils.getNthNT(term, ntId)
    termExpanded = ReprUtils.replaceNthNT(term, ntId, subTerm)
    return termExpanded