def node_from_term(asker, quoted_term):
    head = asker.ask(fields.get_field(representations.head(), quoted_term)).firm_answer
    bindings = asker.ask(fields.get_field(representations.bindings(), quoted_term)).firm_answer
    return asker.reply(answer=properties.simple_add_modifier(
        node(head, T.empty_list()),
        children_on_expanded(bindings)
    ))
def convert(asker, value, req):
    starting_cost = asker.cost
    def check(x):
        return properties.check_firmly(asker, req, representations.quote(x))

    if check(value):
        return asker.reply(answer=value)

    #TODO in the long run we might want to leave properties in if they can simplify the conversion
    old_modifier = value.modifier
    stripped = value.simple_update(_modifier=properties.trivial())
    id = stripped.id
    result = None
    if (id, req.id) in conversion_cache:
        result = conversion_cache[(id, req.id)]
    if result is None:
        for form in synonyms[id]:
            if check(form):
                result = form
    if result is None:
        response = asker.ask(raw_convert(value, req))
        if response.has_answer():
            result = response.answer
        else:
            return asker.reply()
    synonyms[id].add(result)
    conversion_cache[(id, req.id)] = result
    #FIXME what an ugly hack; this sort of thing will hopefully be done automatically
    if (asker.cost - starting_cost > 30 and
            booleans.ask_firmly(asker, nicer_representation(
                representations.quote(value),
                representations.quote(result),
                req
            ))):
        asker.set_repr(value, representations.quote(result))
    return asker.reply(answer=properties.simple_add_modifier(result, old_modifier))
def translate_removal(asker, property, old, new, to_cut):
    if convert.to_bool(asker.ask(builtins.equal(to_cut, object)).firm_answer):
        return asker.reply(answer=new)
    else:
        return asker.reply(answer=properties.simple_add_modifier(new, property))
 def simple_translate(asker, property, update, input, output):
     reduced_update = convert.reduce(asker, update)
     if reduced_update.head not in exclude:
         return asker.reply(answer=properties.simple_add_modifier(output, property))
def translate_both(asker, update, input, output, a, b):
    intermediate = asker.ask(reintroduce_modifier(a, update, input, output)).firm_answer
    with_a = properties.simple_add_modifier(input, a)
    return asker.ask_tail(reintroduce_modifier(b, update, with_a, intermediate))
def translate_composite_held_arg(asker, property, transferring_across, input, object, update):
    if convert.ask_firmly(asker, builtins.equal(update, transferring_across)):
        if convert.ask_firmly(asker, builtins.equal(input, object)):
            return asker.reply(answer=held_update(update, properties.simple_add_modifier(object, property)))
def has_pointer_now(asker, object):
    if convert.check_hard(asker, has_pointer(), object):
        result = updates.update(updates.remove_modifier(is_pointer()), object)
    else:
        result = properties.simple_add_modifier(result, has_pointer())
    return asker.reply(answer=result)
def is_pointer_now(asker, object):
    result = updates.update(updates.remove_modifier(has_pointer()), object)
    result = properties.simple_add_modifier(result, is_pointer())
    return asker.reply(answer=result)
def toggle_expanded(asker, object):
    if convert.check_hard(asker, is_expanded(), object):
        result = updates.update(updates.remove_modifier(is_expanded()), object)
    else:
        result = properties.simple_add_modifier(object, is_expanded())
    return asker.reply(answer=result)