
# factsCG.py
# Andrew Davison, ad@coe.psu.ac.th, May 2025
'''
  Generate a simple callgraph for factorial(N)
  implemented using recursion.
'''

import sys
import graphviz


TEMP_FNM = 'temp_graph'


def fact(n, caller, nCount, edgeLabel):
  nodeNm = 'N'+str(nCount)  # to generate a unique name
  if n <= 1:
    dg.node(nodeNm, "fact("+str(n)+") ↑ 1")
                    # fact(n) returns 1
    dg.edge(caller, nodeNm, label=edgeLabel)
    ''' caller calls nodeNm to do the rest of the
        calculation in the edgeLabel code
    '''
    return 1
  else:
    res = n*fact(n-1, nodeNm, nCount+1, " "+str(n)+" x ...")
                    # recurse first to get the result
    dg.node(nodeNm, "fact("+str(n)+") ↑ " + str(res))
                    # fact(n) returns res
    dg.edge(caller, nodeNm, label=edgeLabel)
    return res

# -------------------------

n = int(input("n=? "))   # use 5 or 7

dg = graphviz.Digraph(format='png')
dg.attr(label='Callgraph for factorial ' + str(n))

dg.node('main')
res = fact(n, 'main', 1, "")
print(f"fact({n}) = {res}")

dg.render(filename=TEMP_FNM, view=True, cleanup=True)
