“…Algorithm 1 will terminate with either an adapter that produces equivalence between the target and inner functions for all side-effects, or an indication that the functions cannot be made equivalent using the adapter family we specify. Algorithm 1 first initializes the current adapter to a default Input : Pointers to the target function T and inner function I Output: (argument adapter A, return value adapter R) or null [1] A ← default-function-args-adapter; [2] R ← default-return-value-adapter; [3] test-list ←empty-list; [4] while true do [5] counterexample ← CheckAdapter (A, R, T, I); [6] if counterexample == null then [7] return (A, R); [8] else [9] test-list.append(counterexample); [10] end [11] (A, R) ← SynthesizeAdapter (test-list, T, I); [12] if A == null then [13] return null; [14] end [15] end Algorithm 1: Counterexample-guided adapter synthesis Input : Concrete adapter A for function arguments and R for return value, target function pointer T, inner function pointer I Output: Counterexample to the given adapter or null [1] args ← symbolic; [2] while execution path available do [3] T-return-value, T-side-effects ← T(args); [4] I-return-value, I-side-effects ← I(adapt(A, args)); [5] if ! (equivalent(T-side-effects, I-side-effects) and equivalent(T-return-value, adapt(R, I-return-value))) then [6] return concretize(args); [7] end [8] end [9] return null; Algorithm 2: CheckAdapter used by Algorithm 1 adapter.…”