How to convert a rule to a memorization function?

All the methods below basically create for each rule k -> g[a, b, c,...] a code of the form

mem : k[t_] := mem = g[a[t], b[t], c[t],...]

which is then executed. The usage is the same for all three:

ClearAll[a, b, c, d, mem];
toMemo[t][rules1]

They also work for multivariate definitions, such as toMemo[s, t][rules].

Method 1

toMemo[args___][rules_] := 
  With[{keypat = Alternatives @@ Keys[rules], 
    a = Sequence @@ Function[x, x_, Listable][{args}]
    },
   (Insert[Hold[mem : #1[a], Set[mem]],
         #2 /. w : keypat :> w[args],
         {2, -1}] & @@@ rules) /. Hold -> SetDelayed;
   ];

Method 2

toMemo[args___][rules_] := 
  With[{k = Keys@rules, v = Values@rules, 
    a = Sequence @@ Function[x, x_, Listable][{args}]},
   ReleaseHold@MapThread[
      Hold@(mem : #1[a] := mem = #2) &,
      {k, v /. f : Alternatives @@ k :> f[args]}
      ];
   ];

Method 3

toMemo[args___][rules_] := 
  With[{k = Keys@rules, a = Function[x, x_, Listable][{args}]},
   Block[{Set, SetDelayed},
      rules /.  HoldPattern[f_ -> body_] :>
        ((mem : f @@ a := mem = #) &@
          (body /. v : Alternatives @@ k :> v[args]))
      ] // Identity;
   ];

Does this do what you want?

 {a[t] -> Sin[t], b[t] -> 
   (a[t]*Cos[t])/(2 + a[t]), 
  c[t] -> 1 + b[t]^2 + 
    a[t]*Sin[t], d[t] -> 
   (-b[t])*c[t] + c[t]^2 + 
    b[t]*Cos[t]} /. {(name_[arg_] -> val_) :> 
   With[{name = name}, (name[dummy_] := 
      name[dummy] = With[{arg = dummy}, val])]}

After executing this, we can call

a[1]; b[1]; c[1]; d[1];

If we now check their DownValues with e.g. ?a or DownValues[a] we find that results have been memoized.

Note that the order in which these functions are called matters for what is memoized. If we call e.g. b[2] before we have called a[2] then the DownValues for b will contain calls to a for which no appropriate memoization has occured, so that will take away the benefit of memoization.