# frozen_string_literal: true require 'simp_rules' # TODO: natural numbers :) # TODO: little lang that transpiles to ruby # unnecessary if i standardize on parenthezing every binary op anyway! def lispify(bla) if bla.is_a? Array l = bla[0] op = bla[1] r = bla[2] [op, [lispify(l), lispify(r)]] else bla end end # doesn't account for actually important stuff, gonna need to do equal' def simp_rule(); end def simp(expr, rules = SIMP_RULES, limit: 413) expr = expr.dup limit.times do rules.each do |rule| expr = simp_single(expr, rule) end end expr end def simp_single(expr, rule) if rule.concrete? expr = simp_applied_rule(expr, rule) else targets = potential_rule_targets(expr) targets.each do |target| concrete_rule = rule.clone.concrete(target) expr = simp_single(expr, concrete_rule) end end expr end def simp_applied_rule(expr, rule) lhs = rule.lhs rhs = rule.rhs if expr == lhs rhs elsif expr.is_a? Array expr.map { |expr| simp_applied_rule(expr, rule) } else expr end end def potential_rule_targets(expr) if expr.is_a? Array (expr + expr.flatten).uniq else [expr] end end